正则表达式

正则表达式

  Java提供了Pattern类和Matcher类支持正则表达式,除此之外String类的以下几个方法也支持正则表达式

  boolean matches(String regex); // 判断该字符串是否匹配表达式regex

  String replaceAll(String regex,String replacement); // 将所有匹配regex的字符串用replacement替换

  String replaceFirst(String regex,String replacement);// 将第一个匹配regex的字符串用replacement替换

  String[] split(String regex); // 以regex为分隔符,将字符串分隔为子串

  正则表达式是一个用于匹配字符串的模板,可以匹配一批字符串,所以创建正则表达式就是创建一个特殊的字符串。


创建正则表达式
  x                         字符x,x可代表任何合法的字符
  \0nnn                     八进制数0nnn所表示的字符
  \xhh                      十六进制数0xhh表示的字符
  \uhhhh                    十六进制值0xhhhh表示的UNICODE字符
  \t                        制表符 \u0009
  \n                        换行 \u0000A
  \r                        回车 \u000D
  \f                        换页符 \u000C
  \a                        报警符 \u0007
  \e                        Esc \u001B
  \cx                       x对应的控制符
  
  特殊字符
  \\                        反斜线
  $                         匹配一行结尾,要匹配$,使用\$
  ^                         匹配一行的开头,要匹配^,使用\^
  ()                        标记子表达式的开始和结束位置,要匹配()时使用\(和\)
  []                        用于确定中括号表达式的开始和结束位置,要匹配[]时使用\[和\]
  {}                        用于标记前面的子表达式的出现频度,要匹配{}时使用\{和\}
  *                         指定前面的子表达式可以出现零次或多次,要匹配*时使用\*
  +                         指定前面子表达式可以出现一次或多次,要匹配+时使用\+
  ?                         指定前面的子表达式可以出现零次或一次,要匹配时使用\?
  .                         匹配除换行符\n之外的任何字符,要匹配时使用\.
  \                         用于转义下一个字符,或指定八进制或十六进制字符,要匹配时使用\\
  |                         指定两项之间任选一项.要匹配时使用\|
  
  预定义字符
  .                         匹配任何字符
  \d                        数字(digit) 等价于[0-9]
  \D                        非数字 等价于[^0-9]
  \s                        空白符号(space) [\t\r\n\f空格]
  \S                        非空白符号
  \w                        单独字符(word) [a-zA-Z_0-9]
  \W                        非单独字符(26个字母大小写数字及下划线) [^a-zA-Z_0-9]
  结合d-digit,s-space,w-word,大写是他们的相反的形式
  
  方括号表达示
  表示枚举,如[abc]表示a,b,c其中任意一个字符
  表示范围(-),如[a-f]表示a~f内的任意字符,[\\u0041-\\u0056]表示十六进制字符\u0041到\u0056范围内的字符
  范围可以组合,如[a-fA-F]表示a~f内的任意字符不分大小写.
  表示求否^,如[^abc]表示a,b,c以外的任意字符,[^a-f]表示a~f以外的任意字符
  表示与运算(&&),如[a-z&&[def]]表示a-z与[def]的交集,即a,ef
  表示并运算,如[a-d[m-p]],表示[a-dm-p],即a~d或m~p中的任意字符
  
  正则表达式还支持圆括号表达式,用于将多个表达式组成一个表达式,圆括号中可以使用|运算符.
  如"(public|protected|private)"用于匹配java的三个访问控制符之一.
  
  边界匹配符
  ^                         行的开头
  $                         行的结尾
  \A                        输入的开头
  \Z                        输入结尾,公用于最后的结束符
  \z                        输入的结尾
  \b                        一个单词的边界
  \B                        一个非单词的边界
  \G                        前一个匹配的结束
  
  数量标识符
  贪婪模式      勉强模式           占用模式           说明
  X?            X??                X?+                X表达式出现0次或1次
  X*            X*?                X*+                X表达式出现0次或多次
  X+            X+?                X++                X表达式出现1次或多次
  X{n}          X{n}?              X{n}+              X表达式出现n次
  X{n,}         X{n,}?             X{n,}+             X表达式最少出现n次
  X{n,m}        X{n,m}?            X{n,m}+            X表达式最少出现n次,最多出现m次

使用正则表达式
  使用Pattern和Matcher来使用正则表达式,Pattern对象是正则表达式编译后在内存中的表示形式,因此表达式字符串必须先被编译成Pattern对象,
 然后再利用该对象创建对应的Matcher对象.执行匹配所涉及的状态保留在Matcher对象中,多个Matcher对象可共享一个Pattern对象.
  Pattern p = Pattern.compile("a*b"); // 将一个字符串编译成Pattern对象
  Matcher m = p.matcher("aaaaab");  // 使用Pattern对象创建Matcher对象
  boolean b = m.matches(); // 返回结果 true
  上面3行代码等效于:
  boolean b = Pattern.matches("a*b", "aaaaab");
  但采用这种形式每次都需要重新编译Pattern对象,不能复用已编译的Pattern对象,效率不高.
  
  Pattern是不变类,可供多个并发线程安全使用.

      static Pattern compile(String regex);
      static Pattern compile(String regex, int flag);
      flag参数:
      Pattern.CANON_EQ              
          两个字符当且仅当它们的完全规范分解相匹配时,才是匹配的.
          如,表达式a\u030A就会匹配字符串?
          默认情况下不会考虑规范的等价性
      Pattern.CASE_INSENSITIVE  
          大小写不敏感的匹配假定只有US-ASCII字符集中的字符才能进行.
          这个模式匹配不必考虑大小写.
          通过指定UNICODE_CASE标记及结合此标记,基于Unicode的大小写不敏感的匹配就可以开启了
          可通过嵌入(?i)开启,如regex中增加(?i)
      Pattern.COMMENTS
          忽略空格.并且以#开始直到行末的注释也会被忽略掉
          可通过嵌入(?x)开启Unix的行模式
      Pattern.DOTALL
          dotall模式中,"."匹配所有字符,包括行终结符.默认情况下,"."不匹配行终结符
          可通过嵌入(?s)开启dotall模式
      Pattern.MULTILINE
          多行模式下,^和$分别匹配一行的开始和结束.^还匹配输入的字符串开始,而$还匹配输入的字符串的结尾.
          默认情况下,这些表达式只匹配输入的完整字符串的开始和结束.
          可通过嵌入(?m)开启
      Pattern.UNICODE_CASE
          指定这个标记并且开启CASE_INSENSITIVE时,大小写不敏感的匹配将按照与Unicode标准相一致的方式进行.
          默认情况下是US-ASCII字符集中的字符才能进行大小写不敏感的匹配
          可通过嵌入(?u)开启
      Pattern.UNIX_LINES
          在这种模式下,在.^$行为中,只识别行终结符\n
          可通过嵌入(?d)开启
      可以使用|操作符组合多个标记的功能.
  Matcher类提供以下几个常用方法:
   boolean find();
   boolean find(int start);            // 返回目标字符串中是否包含与Pattern匹配的子串
   String group();                     // 返回上一次匹配的子串
   int start();                        // 返回上一次与Pattern匹配的子串在目标字符中的开始位置
   int end();                          // 返回上一次与Pattern匹配的子串在目标字符串中的结束位置加1
   boolean lookingAt();                // 返回目标字符串前面部分与Pattern是否匹配
   boolean matches();                  // 返回整个目标字符串与Pattern是否匹配
   Matcher reset(CharSequence input);  // 将现有的Matcher对象应用于一个新的字符序列
   
   
测试代码
    Pattern pattern = Pattern.compile("a*b");
  Matcher matcher = pattern.matcher("acdbab");
  matcher.find();

  Matcher m = Pattern.compile("\\w+").matcher("java is easy!");
  while (m.find()) {
   System.out.println(m.group());
  }
  int i = 0;
  while (m.find(i)) {
   System.out.println(m.group());
   i++;
  }
  while (m.find()) {
   System.out.println(m.group() + ", start=" + m.start() + ", end="
     + m.end());
  }

  String[] mail = { "baidu@126.com", "wawa@abc.xx", "aaa@lii.com@jj.org"};
  String mailRegex = "\\w{3,20}@\\w+\\.(com|org|cn|net|gov)";
  Pattern mailPattern = Pattern.compile(mailRegex);
  Matcher matcher2 = null;
  for (String string : mail) {
   if (matcher2 == null) {
    matcher2 = mailPattern.matcher(string);
   } else {
    matcher2.reset(string);
   }
   System.out.println(string + "是否匹配一个邮件地址?" + (matcher2.matches()));
   System.out.println(string + " use lookingAt ?" + (matcher2.lookingAt()));
  }
运行结果
java
is
easy
java
ava
va
a
is
is
s
easy
easy
asy
sy
y
java, start=0, end=4
is, start=5, end=7
easy, start=8, end=12
baidu@126.com是否匹配一个邮件地址?true
baidu@126.com use lookingAt ?true
wawa@abc.xx是否匹配一个邮件地址?false
wawa@abc.xx use lookingAt ?false
aaa@lii.com@jj.org是否匹配一个邮件地址?false
aaa@lii.com@jj.org use lookingAt ?true

posted @ 2015-12-10 19:25  阿Hai  阅读(299)  评论(0编辑  收藏  举报