学习这个东西,菜鸟主要参考的是这两篇文章:Java正则多字符串匹配替换(网址:http://www.jb51.net/article/34154.htm)、学习正则表达式:Matcher类(网址:http://www.java3z.com/cwbwebhome/article/article8/81313.html?id=3138

  首先要看懂下面的符号的意思

  [...] 位于括号之内的任意字符

  [^...] 不在括号之中的任意字符

  . 除了换行符之外的任意字符,等价于[^\n]

  \w 任何单字字符, 等价于[a-zA-Z0-9]

  \W 任何非单字字符,等价于[^a-zA-Z0-9]

  \s 任何空白符,等价于[\ t \ n \ r \ f \ v]

  \S 任何非空白符,等价于[^\ t \ n \ r \ f \ v]

  \d 任何数字,等价于[0-9]

  \D 除了数字之外的任何字符,等价于[^0-9]

  [\b] 一个退格直接量(特例)

 

  {n, m} 匹配前一项至少n次,但是不能超过m次

  {n, } 匹配前一项n次,或者多次

  {n} 匹配前一项恰好n次

  ? 匹配前一项0次或1次,也就是说前一项是可选的. 等价于 {0, 1}

  + 匹配前一项1次或多次,等价于{1,}

  * 匹配前一项0次或多次.等价于{0,}

 

  | 选择.匹配的要么是该符号左边的子表达式,要么它右边的子表达式

  (...) 分组.将几个项目分为一个单元.这个单元可由 *、+、?和|等符号使用,而且还可以记住和这个组匹配的字符以供此后引用使用

  \n 和第n个分组所匹配的字符相匹配.分组是括号中的子表达式(可能是嵌套的).分组号是从左到右计数的左括号数

 

  ^ 匹配的是字符的开头,在多行检索中,匹配的是一行的开头

  $ 匹配的是字符的结尾,在多行检索中,匹配的是一行的结尾

  \b 匹配的是一个词语的边界.简而言之就是位于字符\w 和 \w之间的位置(注意:[\b]匹配的是退格符)

  \B 匹配的是非词语的边界的字符

  

  Matcher类有个非常重要的概念叫做:组(Group)

  例如:\w(\d\d)(w+)

  这个正则表达式中是用()来划分组的:

  第0组:不看括号,这个的表达式就是0组\w(\d\d)(w+)

  第1组:(\d\d)

  第2组:(\w+)

  然后来做做例子:(为了使\是有效的所以要用\\放在字符串中)

  

 1 import java.util.regex.Matcher;
 2 import java.util.regex.Pattern;
 3 
 4 public class Calender {
 5     public static void main(String[] args) {    
 6      Pattern p = Pattern.compile("(\\d\\d)\\1");//第一组是(\\d\\d)表示2个任何数字,而后面的\1表示后面的两个数要和前面两个一样
 7      String s = "1212";//可以改成2525之类的前两个和后两个相同的数字,但不能改成1213这样的(12和13不同)
 8      Matcher m = p.matcher(s);//若是Pattern.compile("(\\d(\\d))\\2")则需改成122才对
 9      if(m.find()){
10             int gc = m.groupCount();
11             for(int i = 0; i <= gc; i++)
12                 System.out.println("group " + i + " :" + m.group(i));
13         }
14     }
15 
16 }

  输出结果为:

    group 0 :1212
    group 1 :12

  现在来试一个验证邮箱的有效性的例子:

 1 import java.util.regex.Matcher;
 2 import java.util.regex.Pattern;
 3 
 4 public class Calender {
 5     public static void main(String[] args) {  
 6         /**
 7          * ^要以字符为开头才能匹配
 8          * 第一组:([a-z0-9_\\.\\-\\+]+)---a-z或0-9或_或.或-或+都可以匹配
 9          * 第二组:([\\da-z\\.\\-]+)---数字或a-z或.或-都可以匹配
10          * 第三组:([a-z\\.]{2,6})---a-z或.匹配最少2次最多6次
11          * $要以字符为结尾才能匹配
12          */
13         Pattern p = Pattern.compile("^([a-z0-9_\\.\\-\\+]+)@([\\da-z\\.\\-]+)\\.([a-z\\.]{2,6})$");
14         String s = "test_-.+@qq.163.sina.com";
15         Matcher m = p.matcher(s);
16      if(m.find()){
17             int gc = m.groupCount();
18             for(int i = 0; i <= gc; i++)
19                 System.out.println("group " + i + " :" + m.group(i));
20         }
21     }
22 }

 

  输出结果为:

    group 0 :test_-.+@qq.163.sina.com
    group 1 :test_-.+
    group 2 :qq.163.sina
    group 3 :com

  又来试试例子:

 1 import java.util.regex.Matcher;
 2 import java.util.regex.Pattern;
 3 
 4 public class Calender {
 5     public static void main(String[] args) { 
 6         /**
 7          * 第一组:(name|value)---选择name如果没有则选择value
 8          * \"---引号
 9          * 第二组:(.+?)---.表示匹配除了换行符之外任意字符、+表示匹配前一项1或n次、?表示匹配前一项0或1次(表示前一项可选)
10          * 如果只是(.+)没有?则它一直要到第四个引号前才会停止
11          * 如果只是(.?)没有+则name的值必须是一个或零个字符的
12          * 不要把(.+?)理解成单纯的符号了
13          */
14         Pattern p = Pattern.compile("android:(name|value)=\"(.+?)\"");
15         String s = "<meta-data android:name=\"appid\" android:value=\"joy\"></meta-data>";
16         Matcher m = p.matcher(s);
17      if(m.find()){
18             int gc = m.groupCount();
19             for(int i = 0; i <= gc; i++)
20                 System.out.println("group " + i + " :" + m.group(i));
21         }
22     }
23 }

  输出结果:

    group 0 :android:name="appid"

    group 1 :name

    group 2 :appid

  上面这个例子菜鸟纠结蛋疼的试了半天。

  警句:菜鸟用爪挖,看者需谨慎,切莫听一面之词,徒走曲折之路。

posted on 2013-07-23 15:04  菜鸟用爪挖  阅读(268)  评论(0编辑  收藏  举报