admin管理员组

文章数量:1579387

1.简单认识正则:

public classTest {public static voidmain(String[] args) {//简单认识正则

p("abc".matches("..."));

p("a8729a".replaceAll("\\d", "-"));

}public static voidp(Object o){

System.out.println(o);

}

}

一个.代表一个字母

true

a----a

2.简单认识Pattern和Matcher:

/*** 比下面一句话的好处:

* 1.Patternpile将正则表达式先编译了,速度更快;

* 2.Pattern 和Matcher有更多的方法,是String.matches所没有的;*/Pattern p= Patternpile("[a-z]{3}");

Matcher m= p.matcher("fgh");

p(m.matches());

p("fgh".matches("[a-z]{3}")); //相当于上面三句话

true

true

解释:

/**

* Pattern:模式,[a-z]{3}的这种模式。

* Matcher:匹配器;[a-z]{3}的这种模式去匹配"fgh"这个字符串;

* 匹配这个字符串的过程之中,要注意有可能产生多个结果,匹配的结果会保留在Matcher对象m里面。

* 这个结果是匹配还是不匹配呢?调用m.matches();

*/

3.初步认识. * + ?

/*** 初步认识 . * +

* . 任意一个字符

* * 0个或多个

* + 1个或多个

* ? 0个或1个,可有可无。*/p("a".matches(".")); //true

p("aa".matches("aa")); //true

p("aaaa".matches("a*")); //true

p("aaaa".matches("a+")); //true

p("".matches("a*")); //true

p("aaaa".matches("a?")); //false

p("".matches("a?")); //true

p("a".matches("a?")); //true

p("214523145234532".matches("\\d{3,100}")); //true

p("192.168.0.aaa".matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}")); //false

p("192".matches("[0-2][0-9][0-9]")); //true

解释:

.是一个特殊的字符,用转义字符,所以写\.       可是\在正则表达式里面确实是\,但是在java里面比较特殊,用两个\\。

所以\\.代表.这个字符。

4.范围:

/*** 范围

* []里面匹配一个字符。中括号里面写的再长,也是匹配一个字符*/p("a".matches("[abc]"));

p("a".matches("[^abc]")); //取反,除了abc之外的内容

p("A".matches("[a-zA-Z]")); //大写字母或小写字母

p("A".matches("[a-z]|[A-Z]")); //这种写法和上面写法一样

p("A".matches("[a-z[A-Z]]")); //也是a-z或者A-Z的意思

p("R".matches("[A-Z&&[RFG]]")); //A-Z中的,并且是RFG之一的

true

false

true

true

true

true

5.认识 \s  \w   \d   \

/*** 认识 \s \w \d \

* \s 空白字符,包含空格,tab、换行、制表符、回车

* \w 构成单词的字符[a-zA-Z_0-9]

* 在java里面字符串\\代表的是一个反斜线\;用正则表达式去匹配一个反斜线\:

* 正则表达式本身要匹配一个反斜线的话,需要用两个反斜线;

* 然后你要用字符串把这个正则表达式表现出来的时候,每一个反斜线都要用两个反斜线替代;

* 在java里面一个反斜线\和后面的字符会合在一起,构成一个转义字符;所以在java里面一个反斜线\必须用两个反斜线来替代;*/p(" \n\r\t".matches("\\s{4}"));

p(" ".matches("\\S"));

p("a_8".matches("\\w{3}"));

p("abc888&^%".matches("[a-z]{1,3}\\d+[&^#%]+"));

p("\\".matches("\\\\"));//如果写:p("\\".matches("\\"))的话://matches("\\")里的\\会被正则表达式认为成它是一个反斜线;//在正则表达式里面,一个\也会是一个特殊字符,它会和后面的字符合在一起,那第一个双引号"又没有配对的了;//所以要在正则表达式里,匹配一个\,要写成:\\\\

true

false

true

true

true

解释:

/**

* 怎么用正则表达式匹配一个反斜线呢?

* 在java里面 一个\必须用两个\\来替代。

* 正则表达式本身要匹配一个反斜线,使用\\来匹配的,然后你要用字符串把这个正则表达式表现出来的时候,每一个\都要用两个\\替代;

* 所以要在正则表达式里面匹配一个反斜线,写4个\

*/

6.POSIX Style风格:

//POSIX Style//参考API \p{Lower} A lower-case alphabetic character: [a-z]

p("a".matches("\\p{Lower}")); //true

6.boundary  边界匹配:

/*** boundary 边界匹配

* ^ 位于[]外面,代表开头

* \b 一个单词的边界;单词边界:空格、空白字符、各种各样的特殊字符、换行的时候等等,都算单词边界;*/p("hello sir".matches("^h.*")); //true

p("hello sir".matches(".*ir$")); //true

p("hello sir".matches("^h[a-z]{1,3}o\\b.*")); //true

p("hellosir".matches("^h[a-z]{1,3}o\\b.*")); //false

7.匹配空白行:

/*** white lines空白行:*/

//以空白字符开头的并且不是换行符,紧跟0个或多个,以换行符结尾;

p(" \n".matches("^[\\s&&[^\\n]]*\\n$")); //true

8.匹配Email地址:

/*** 匹配Email地址的正则表达式

* 构成单词的字符或者是.- 出现1次或多次 @ 单词字符或.- 1次或多次 . 单词字符或.- 1次或多次

* 注意.是元字符代表任意字符,这里表示.要用 \\. 代表*/p("asdfasdfsafsf@dsdfsdf".matches("[\\w[.-]]+@[\\w[.-]]+\\.[\\w]+")); //true

.写在[ ]里面表示.          [.-]表示.或者-

例子:

p("ab4com".matches("[a-z]{2}[.]{1}\\w{3}"));      ——false,因为要求两个a-z的字母后面紧接的是.   所以false

9.matches()、find()、lookingAt():

/*** matches find lookingAt

* matches 是否匹配 matches()永远是匹配整个字符串

* m.find(): 找一个和模式相匹配的子串;是找子串,而不是匹配整个字符串;

* 找着一个之后,正则引擎会将找到的子串截掉,然后从剩下的字符串里再找;

* lookingAt(): 每次找,都是从开头位置找;*/Pattern p= Patternpile("\\d{3,5}");

String s= "123-34345-234-00";

Matcher m=p.matcher(s);

p(m.matches());//false

p(m.find());//true

p(m.find()); //true

p(m.find()); //false

p(m.find()); //false//上面的结果解释://m.matches()运行时,开始分析"123-34345-234-00",分析到123-发现已经不匹配了,停止,返回false;//m.find()执行,继续从34345-234-00开始找,find第一个34345返回true;find第二个234返回true,后面两个false

1 /**

2 * start():找到的字符串的起始位置;3 * end(): 找到的字符串的结束位置;是找到的字符的后面一个位置;4 * 必须能够找到,否则打印会报错;5 */

6 Pattern p = Patternpile("\\d{3,5}");7 String s = "123-34345-234-00";8 Matcher m =p.matcher(s);9 p(m.matches()); //false

10 m.reset();11 p(m.find()); //true

12 p(m.start() + "-" + m.end()); //0-3

13

14 p(m.find()); //true

15 p(m.start() + "-" + m.end()); //4-9

16

17 p(m.find()); //true

18 p(m.start() + "-" + m.end()); //10-13

19

20 p(m.find()); //false

21

22 p(m.lookingAt());23 p(m.lookingAt());24 p(m.lookingAt());25 p(m.lookingAt());26

27 //上面结果解释:28 //m.matches()执行,分析到123-发现已经不匹配了,停止,返回false;29 //m.reset()执行,m又回到了"123-34345-234-00"的开头位置。从头开始分析(回到初始的状态);30 //m.lookingAt():每次从开头位置找,每次找到123,就都返回true

10.replacement:

1 /**

2 * replacement3 * group(): 输出匹配到的子串;整个的正则表达式可以看作组号为0的一个组;4 */

5 //将下面的字符串中java全都替换成大写的:

6 Pattern p = Patternpile("java", Pattern.CASE_INSENSITIVE);7 Matcher m = p.matcher("java Java JAVa JaVa IloveJAVA you hateJava");8 p(m.replaceAll("JAVA"));

JAVA JAVA JAVA JAVA IloveJAVA you hateJAVA

1 //将下面字符串中,找到的java,第奇数个替换成JAVA,第偶数个替换成java

2 Pattern p = Patternpile("java", Pattern.CASE_INSENSITIVE);3 Matcher m = p.matcher("java Java JAVa JaVa IloveJAVA you hateJava afasdfasdf");4 StringBuffer buf = newStringBuffer();5 int count = 0;6 while(m.find()){7 count++;8 if(count%2 == 0){9 m.appendReplacement(buf, "java");10 }else{11 m.appendReplacement(buf, "JAVA");12 }13 }14 m.appendTail(buf);15 p(buf);

JAVA java JAVA java IloveJAVA you hatejava afasdfasdf

11.分组:group:

1 /**

2 * group 分组3 * group(): 返回整个正则表达式所匹配的子串;4 */

5 Pattern p = Patternpile("\\d{3,5}[a-z]{2}");6 String s = "123aa-34345bb-234cc-00";7 Matcher m =p.matcher(s);8 while(m.find()) {9 p(m.group());10 }

123aa

34345bb

234cc

1 //将上面字符串中,匹配的3-5位的数字拿出来:2 //要知道第几组:数左边的小括号,第一个小括号为第1组,第二个小括号为第2组...

3 Pattern p = Patternpile("(\\d{3,5})([a-z]{2})");4 String s = "123aa-34345bb-234cc-00";5 Matcher m =p.matcher(s);6 while(m.find()){7 p(m.group(1));8 }

123

34345

234

12.抓取网页Email地址的例子:

1 packagecom.cy.regexp;2

3 importjava.io.BufferedReader;4 importjava.io.BufferedWriter;5 importjava.io.FileNotFoundException;6 importjava.io.FileReader;7 importjava.io.FileWriter;8 importjava.io.IOException;9 importjava.util.regex.Matcher;10 importjava.util.regex.Pattern;11

12 public classEmailSpider {13

14 @SuppressWarnings("resource")15 public static voidmain(String[] args) {16 try{17 BufferedReader br = new BufferedReader(new FileReader("D:\\fromEmail.html"));18 BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\findEmail.txt"));19

20 String line = "";21 while((line = br.readLine()) != null){22 writeToFile(line, bw);23 }24 bw.flush();25 } catch(FileNotFoundException e) {26 e.printStackTrace();27 } catch(IOException e) {28 e.printStackTrace();29 }30 }31

32 public static void writeToFile(String line, BufferedWriter bw) throwsIOException{33 Pattern p = Patternpile("[\\w[.-]]+@[\\w[.-]]+\\.[\\w]+");34 Matcher m =p.matcher(line);35 while(m.find()){36 bw.write(m.group());37 bw.newLine();38 }39 }40 }

View Code

13.修饰符、限定词:

1 /**

2 * qulifiers 修饰符 限定词 在数量后面 加限定词3 * Greedy quantifiers 贪婪的;默认的写法都是贪婪的;x? x* x+ x{n} x{n,} x{n,m}都是贪婪的4 * Reluctant quantifiers: 勉强的,非贪婪的,和Greedy正好相反:x?? x*? x+? ...5 * Possessive quantifiers: 独占的;和贪婪的类似,.{3,10}+,一下吞进去10个字符,不匹配时但是不往外吐,就是找不着;6 */

7

8 Pattern p = Patternpile(".{3,10}[0-9]");9 String s = "aaaa5bbbb6";10 Matcher m =p.matcher(s);11 if(m.find()){12 p(m.start() + "-" + m.end()); //0-10

13 }else{14 p("not match!");15 }16

17 Pattern p = Patternpile(".{3,10}?[0-9]");18 String s = "aaaa5bbbb6";19 Matcher m =p.matcher(s);20 if(m.find()){21 p(m.start() + "-" + m.end()); //0-5

22 }else{23 p("not match!");24 }25

26 Pattern p = Patternpile(".{3,10}+[0-9]");27 String s = "aaaa5bbbb6";28 Matcher m =p.matcher(s);29 if(m.find()){30 p(m.start() + "-" +m.end());31 }else{32 p("not match!"); //not match!

33 }34

35 Pattern p = Patternpile(".{3,10}+[0-9]");36 String s = "aaaa5bbbb68";37 Matcher m =p.matcher(s);38 if(m.find()){39 p(m.start() + "-" + m.end()); //0-11

40 }else{41 p("not match!");42 }

14.non-capturing groups 非捕获组:

1 /**

2 * non-capturing groups3 * 非捕获组: 如果符合这个条件就捕获;如果不符合这个条件就不捕获4 */

5 //这个正则表达式匹配 3个字母的后面紧跟的是一个a,像这样的才去匹配它;而且这个a不被抓出来6 //?=a 不捕获这个a7 //(?=X) X, via zero-width positive lookahead lookahead从头开始看

8 Pattern p = Patternpile(".{3}(?=a)");9 String s = "444a66b";10 Matcher m =p.matcher(s);11 while(m.find()) {12 p(m.group()); //444

13 }14

15 //前面是a的,3个字母

16 Pattern p = Patternpile("(?=a).{3}");17 String s = "444a66b";18 Matcher m =p.matcher(s);19 while(m.find()) {20 p(m.group()); //a66

21 }22

23 //(?!a) 前面不是a的,3个字母

24 Pattern p = Patternpile("(?!a).{3}");25 String s = "444a66b";26 Matcher m =p.matcher(s);27 while(m.find()) {28 p(m.group()); //444 66b

29 }30

31 //3个字母, 后面不是a

32 Pattern p = Patternpile(".{3}(?!a)");33 String s = "444a66b";34 Matcher m =p.matcher(s);35 while(m.find()) {36 p(m.group()); //44a 66b

37 }38

39 //3个字母,从后往前数,不能是a

40 Pattern p = Patternpile(".{3}(?

45 }46

47 //3个字母,从后往前数,是a, 包含a

48 Pattern p = Patternpile(".{3}(?<=a)");49 String s = "444a66b";50 Matcher m =p.matcher(s);51 while(m.find()) {52 p(m.group()); //44a

53 }

View Code

15.back refenrences  向前引用:

1 /**

2 * back refenrences3 * 向前引用;4 * (\\d\\d)匹配两个数字,作为结果;\\1 指的是后面的东西必须和前面第一个group找到的结果一模一样5 * 第一个group找到的是12,后面是12,和前面第1个group找到的东西一样, 所以返回true6 */

7 Pattern p = Patternpile("(\\d\\d)\\1");8 String s = "1212";9 Matcher m =p.matcher(s);10 p(m.matches()); //true11

12 //第2个group抓到的是2,后面的结果要和第2个group抓到的内容一样

13 Pattern p = Patternpile("(\\d(\\d))\\2");14 String s = "122";15 Matcher m = p.matcher(s); //true

16 p(m.matches());

View Code

16.flags的简写:

1      /**

2 * flags的简写3 * DOTALL .可以匹配所有的字符,默认的.是不匹配换行符的;4 * CASE_INSENSITIVE 忽略大小写5 * API: Case-insensitive matching can also be enabled via the embedded flag expression (?i).6 */

7 Pattern p = Patternpile("java", Pattern.CASE_INSENSITIVE);8

9 //(?i) 也是非捕获组 跟上面的写法一模一样,上面写法的简写

10 p("Java".matches("(?i)(java)")); //true

本文标签: 正则表达式懒惰Java