java----正则表达式

来源:互联网 发布:远程教学用什么软件 编辑:程序博客网 时间:2024/06/14 20:35
正则表达式
一、正则表达式
正则表达式:符合一定规则的表达式。
作用:用于专门操作字符串。
特点:用一些特定的符号来表示一些代码操作。简化代码书写。学习正则表达式,就是在学习一些特殊符号的使用。
练习:对QQ号码进行校验。
要求:5~15位,0不能开头,只能是数字。
class Demo{public static void main(String []args) throws Exception{String QQ = "63224d5";if(QQ.length()>=5&&QQ.length()<=15){if(QQ.charAt(0)!='0'){char[] chs = QQ.toCharArray();boolean flag = true;for(int x=0;x<chs.length;x++){if(!(chs[x]>='0'&&chs[x]<='9')){flag = false;break;}}if(flag){System.out.println(QQ);}elseSystem.out.println("非法字符");}else{System.out.println("不能以0开头");}}else{System.out.println("号码长度错误");}}}
分析:这种方式使用了String类中的方法进行组合,完成了需求,但是代码过于复杂。
使用正则表达式
boolean matches(String regex)           告知此字符串是否匹配给定的正则表达式。 
class Demo{public static void main(String []args) throws Exception{String QQ = "21445";String regex = "[1-9][0-9]{4,14}";if(QQ.matches(regex)){System.out.println(QQ);}elseSystem.out.println("不合法");}}
正则表达式
字符 x 字符 x \\ 反斜线字符 \0n 带有八进制值 0 的字符 n (0 <= n <= 7) \0nn 带有八进制值 0 的字符 nn (0 <= n <= 7) \0mnn 带有八进制值 0 的字符 mnn(0 <= m <= 3、0 <= n <= 7) \xhh 带有十六进制值 0x 的字符 hh \uhhhh 带有十六进制值 0x 的字符 hhhh \t 制表符 ('\u0009') \n 新行(换行)符 ('\u000A') \r 回车符 ('\u000D') \f 换页符 ('\u000C') \a 报警 (bell) 符 ('\u0007') \e 转义符 ('\u001B') \cx 对应于 x 的控制符   字符类 [abc] a、b 或 c(简单类) [^abc] 任何字符,除了 a、b 或 c(否定) [a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围) [a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集) [a-z&&[def]] d、e 或 f(交集) [a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去) [a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去)   预定义字符类 . 任何字符(与行结束符可能匹配也可能不匹配) \d 数字:[0-9] \D 非数字: [^0-9] \s 空白字符:[ \t\n\x0B\f\r] \S 非空白字符:[^\s] \w 单词字符:[a-zA-Z_0-9] \W 非单词字符:[^\w]   POSIX 字符类(仅 US-ASCII) \p{Lower} 小写字母字符:[a-z] \p{Upper} 大写字母字符:[A-Z] \p{ASCII} 所有 ASCII:[\x00-\x7F] \p{Alpha} 字母字符:[\p{Lower}\p{Upper}] \p{Digit} 十进制数字:[0-9] \p{Alnum} 字母数字字符:[\p{Alpha}\p{Digit}] \p{Punct} 标点符号:!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ \p{Graph} 可见字符:[\p{Alnum}\p{Punct}] \p{Print} 可打印字符:[\p{Graph}\x20] \p{Blank} 空格或制表符:[ \t] \p{Cntrl} 控制字符:[\x00-\x1F\x7F] \p{XDigit} 十六进制数字:[0-9a-fA-F] \p{Space} 空白字符:[ \t\n\x0B\f\r]   java.lang.Character 类(简单的 java 字符类型) \p{javaLowerCase} 等效于 java.lang.Character.isLowerCase() \p{javaUpperCase} 等效于 java.lang.Character.isUpperCase() \p{javaWhitespace} 等效于 java.lang.Character.isWhitespace() \p{javaMirrored} 等效于 java.lang.Character.isMirrored()   Unicode 块和类别的类 \p{InGreek} Greek 块(简单块)中的字符 \p{Lu} 大写字母(简单类别) \p{Sc} 货币符号 \P{InGreek} 所有字符,Greek 块中的除外(否定) [\p{L}&&[^\p{Lu}]]  所有字母,大写字母除外(减去)   边界匹配器 ^ 行的开头 $ 行的结尾 \b 单词边界 \B 非单词边界 \A 输入的开头 \G 上一个匹配的结尾 \Z 输入的结尾,仅用于最后的结束符(如果有的话) \z 输入的结尾   Greedy 数量词 X? X,一次或一次也没有 X* X,零次或多次 X+ X,一次或多次 X{n} X,恰好 n 次 X{n,} X,至少 n 次 X{n,m} X,至少 n 次,但是不超过 m 次   Reluctant 数量词 X?? X,一次或一次也没有 X*? X,零次或多次 X+? X,一次或多次 X{n}? X,恰好 n 次 X{n,}? X,至少 n 次 X{n,m}? X,至少 n 次,但是不超过 m 次   Possessive 数量词 X?+ X,一次或一次也没有 X*+ X,零次或多次 X++ X,一次或多次 X{n}+ X,恰好 n 次 X{n,}+ X,至少 n 次 X{n,m}+ X,至少 n 次,但是不超过 m 次   Logical 运算符 XY X 后跟 Y X|Y X 或 Y (X) X,作为捕获组   Back 引用 \n 任何匹配的 nth 捕获组   引用 \ Nothing,但是引用以下字符 \Q Nothing,但是引用所有字符,直到 \E \E Nothing,但是结束从 \Q 开始的引用   特殊构造(非捕获) (?:X) X,作为非捕获组 (?idmsux-idmsux)  Nothing,但是将匹配标志i d m s u x on - off (?idmsux-idmsux:X)   X,作为带有给定标志 i d m s u x on - off 的非捕获组  (?=X) X,通过零宽度的正 lookahead (?!X) X,通过零宽度的负 lookahead (?<=X) X,通过零宽度的正 lookbehind (?<!X) X,通过零宽度的负 lookbehind (?>X) X,作为独立的非捕获组 
常见操作
1.匹配matches方法,用规则匹配整个字符串,只有不符合规则,匹配结束,返回false
练习:手机号判断。只有13XXX,15XXX,18XXX。
class Demo{public static void main(String []args) throws Exception{String tel = "15508888888";String regex = "[1][358][0-9]{9}";if(tel.matches(regex))System.out.println("ok");elseSystem.out.println("sorry");}}
2.切割split方法。
class Demo{public static void main(String []args) throws Exception{String name = "zhangsan      lisi    wangwu";String regex = " +";String[] arr= name.split(regex);for(String s : arr){System.out.println(s);}}}

:“.”是特殊符号,“\.”又是正则表达式,所以要想表示一个“.”符号必须转义——“\\.”。“\”也是特殊字符,所以表示一个“\”也必须转义——“\\”。
class Demo{public static void main(String []args) throws Exception{String name = "Demo.java";String regex = "\\.";String[] arr= name.split(regex);for(String s : arr){System.out.println(s);}}}

class Demo{public static void main(String []args) throws Exception{String name = "c:\\abc\\a.txt";String regex = "\\\\";//一个"\"只转义一个"\"String[] arr= name.split(regex);for(String s : arr){System.out.println(s);}}}

练习切叠词
为了让规则结果被重用,可以将规则封装成一个组,用“()”完成。组的出现都有编号,从1开始。要使用已有的组,可以通过“\n”(n代表组编号)的形式获取。
class Demo{public static void main(String []args) throws Exception{String name = "dsadakkkhdeezooo";String regex = "(.)\\1+";String[] arr= name.split(regex);for(String s : arr){System.out.println(s);}}}

3.替换replaceAll方法。
练习:将字符串中出现5次的数字换成“#”号。
class Demo{public static void main(String []args) throws Exception{String str = "asfasf46366ffaso9qw899";String regex = "\\d{5,}";str = str.replaceAll(regex,"#");System.out.println(str);}}

练习:将叠词替换成“#”号。
class Demo{public static void main(String []args) throws Exception{String str = "wkkidssrvjjjyt";System.out.println(str);String regex = "(.)\\1+";str = str.replaceAll(regex,"#");System.out.println(str);}}

练习:将叠词替换成单个字符。“$”获取组里的元素。
class Demo{public static void main(String []args) throws Exception{String str = "wkkidssrvjjjyt";System.out.println(str);String regex = "(.)\\1+";str = str.replaceAll(regex,"$1");System.out.println(str);}}

4.获取:将字符串中符合规则的字串取出。
操作步骤
1.将正则表达式封装成对象。
2.让正则对象和要操作的字符串相关联。
3.关联后获取正则匹配引擎。
4.通过引擎对符合规则的字串进行操作,比如取出。
java.util.regex:正则包。
Pattern:正则对象。
练习:将不超过三个字母的单词取出。
import java.util.regex.*;class Demo{public static void main(String []args) throws Exception{String str = "ming tian jiu yao fang jia le,da jia.";//"\b"为单词边界匹配器String regex = "\\b[a-z]{1,3}\\b";//将规则封装成对象Pattern p = Pattern.compile(regex);//让正则对象和要作用的字符串相关联,获取匹配器对象。Matcher称为引擎或匹配器。Matcher m = p.matcher(str);while(m.find()){System.out.println(m.group());}}}

其实,String类中的matches方法,用的就是PatternMatcher对象来完成的,只不过被String的方法封装后,用起来较为简单,但是功能单一。
易疏忽的地方:
import java.util.regex.*;class Demo{public static void main(String []args) throws Exception{String str = "jiu yao fang jia le,da jia.";String regex = "\\b[a-z]{1,3}\\b";Pattern p = Pattern.compile(regex);Matcher m = p.matcher(str);System.out.println(m.matches());while(m.find()){System.out.println(m.group());}}}

jiu也满足了条件,可是却没有打印出来,疑问这是神马呢?
:和IteratorhasNext一样,m.matches();已经将指针(索引)往后移了一位。所以也就没有打印jiu
练习:将下列字符串转成:我要学编程。
我我.....我我........我要.......要要......要要.......学学.....学学......编编.....程....程程.....程.....程
疑问到底用四种功能中的哪一种呢?或者哪几个呢?
思考方式
1.如果只想知道该字符串是对是错,可以使用匹配
2.想要将已有的字符串变成另一个字符串,可以使用替换
3.想要按照指定的方式变成多个字符串,可以使用切割
4.想要拿到符合要求的字符串字串,可以使用获取
思路
1.可以先将“.”去掉。
2.再将多个重复内容变成单个内容。
class Demo{public static void main(String []args) throws Exception{String str = "我我.....我我........我要.......要要......要要.......学学.....学学......编编.....程....程程.....程.....程";System.out.println(str);str = str.replaceAll("\\.+","");System.out.println(str);str = str.replaceAll("(.)\\1+","$1");System.out.println(str);}}

练习:将ip地址进行顺序的排序。
192.168.1.254 102.49.23.1310.10.10.10 2.2.2.2 8.109.90.30
思路
1.按照每一段需要的最多的“0”进行补齐,那么每一段就会至少保证有3位。
2.将每一段只保留3位,这样,所有的ip地址都是每一段3位。
import java.util.*;class Demo{public static void main(String []args) throws Exception{String str = "192.168.1.254 102.49.23.13 10.10.10.10 2.2.2.2 8.109.90.30";str = str.replaceAll("(\\d+)","00$1");str = str.replaceAll("0*(\\d{3})","$1");String[] arr = str.split(" ");TreeSet<String> ts = new TreeSet<String>();for(String s : arr){ts.add(s);}for(String s : ts){s = s.replaceAll("0*(\\d+)","$1");System.out.println(s);}}}

练习:对邮件地址进行校验。
import java.util.*;class Demo{public static void main(String []args) throws Exception{String mail = "abc123@sina.com";String reg = "[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\\.[a-zA-Z]+)+";System.out.println(mail.matches(reg));}}

常见校验格式
[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\\.[a-zA-Z]+)+(较为精确),简写:[\\w_]+@[\\w_]+(\\.[\\D&&\\w]+)+。
练习:网页爬虫
import java.io.*;import java.net.*;import java.awt.*;import java.awt.event.*;import java.util.regex.*;class DemoIE{private Frame f;private TextField tf;private Button b;private TextArea ta;private Dialog d;private Label l;DemoIE(){init();}public void init(){f = new Frame("MyIE");f.setBounds(400,150,700,500);f.setLayout(new FlowLayout());tf = new TextField(70);f.add(tf);b = new Button("转到");f.add(b);ta = new TextArea();ta.setRows(26);ta.setColumns(78);f.add(ta);d = new Dialog(f,"提示");d.setBounds(500,300,300,100);d.setLayout(new FlowLayout());f.setVisible(true);myEvent();}public void myEvent(){f.addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent e){System.exit(0);}});tf.addKeyListener(new KeyAdapter(){public void keyPressed(KeyEvent e){if(e.getKeyCode()==KeyEvent.VK_ENTER){load();}}});b.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){load();}});}public void load(){ta.setText("");try{String str = tf.getText();//URL url = new URL(new String(str));//String host = url.getHost();//int port = url.getPort();//if(port == -1)//port = 80;//String file = url.getFile();if(!str.startsWith("http://"))str = "http://"+str;URL url = new URL(str);//"http://"+host+":"+port+"//"+file);String host = url.getHost();int port = url.getPort();if(port == -1)port = 80;String file = url.getFile();url = new URL("http://"+host+":"+port+"//"+file);URLConnection conn = url.openConnection();BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));String line = null;while((line = br.readLine())!=null){Pattern p = Pattern.compile("[\\w_]+@[\\w_]+(\\.[\\D&&\\w]+)+");Matcher m = p.matcher(line);while(m.find()){ta.append(m.group()+"\r\n");}}}catch(Exception e){System.out.println("nono");}}public void showDia(String info){l.setText(info);d.setVisible(true);}public static void main(String []args){new DemoIE();}}