卫氏有图腾:正则式,正则表达式,多行匹配,不以某某开头,不区分大小写,2个单元的或操作

来源:百度文库 编辑:偶看新闻 时间:2024/04/27 22:17:11
http://heisetoufa.javaeye.com/blog/227714

文章出处:http://topic.csdn.net/u/20080627/14/8a91b33a-f35c-4303-85b5-e0a8da462202.html

1 多行匹配
2 不以某某开头 ,比如不以www开头
3 不区分大小写
4 2个单元的或操作,比如  www ¦ 3w 都可以这种

火龙果回答:

1:多行匹配

在默认的情况下 . 是不能匹配行结束符的(行结束符有 6 个,具体的可以看看 Pattern 的 API DOC)
同样,可以像不匹配大小写匹配那样使用编译参数:Pattern.DOTALL

如果还得区分大小写的话,还得加上上面说到的 Pattern.CASE_INSENSITIVE 这个,举个例子:

Java代码
  1. import java.util.regex.Matcher;  
  2. import java.util.regex.Pattern;public class Test {  
  3.   
  4.     public static void main(String[] args) {  
  5.         String str =   
  6.                 "                \n" +  
  7.                 "  
  8.                  \n" +  
  9.                 "    
  10.               \n" +  
  11.                 "  
  12.                 \n" +  
  13.                 "
  14.                \n" +  
  15.                 "       Hello World!    \n" +  
  16.                 "    
  17. ";  
  18.         String regex = "(.+?)";  
  19.         Pattern pattern = Pattern.compile(regex);  
  20.         Matcher matcher = pattern.matcher(str);  
  21.         while(matcher.find()) {  
  22.             System.out.println(matcher.group(1).trim());  
  23.         }          
  24.     }  
  25. }  

上面这个是不能从 str 抽取出东西的,因为 td 的后面带有换行符,我们只要更改一下:

Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);

这样就行了,如果 td 还得不区分大小写的话,再改成:

Pattern pattern = Pattern.compile(regex, Pattern.DOTALL | Pattern.CASE_INSENSITIVE);

这样的话,td 哪怕是大写的这个表达式都能把 td 之间的字符区抽取出来。

当然和 Pattern.CASE_INSENSITIVE 一样,Pattern.DOTALL 也有内嵌标志表达式,即 (?s)
s 的意思表示 single-line 就是忽略换行符什么的,只看成单行进行处理。

这个表达式使用内嵌 (?s) 的话可以改为:

String regex = "(?s)(.+?)";

如果还要不区分大小写的话,再加上 i 标志:
String regex = "(?s)(?i)(.+?)";

但这样显得很拖沓,可以把它们合并起来:
String regex = "(?is)(.+?)";    // 秩序无所谓

最后需要说明一下的是,我曾看到过由于不明白 DOTALL,为了让 . 匹配行结束符,直接把表达式写成:

String regex = "((.|\\s)+?)";

这样做是极其危险的,由于选择结构的匹配效率问题,这样做在比较长的字符串时会造成堆栈溢出,
使程序崩溃,如果使用 DOTALL 或者 (?s) 的话就不会出现这种情况。

2:不以某某开头 ,比如不以www开头

Java代码
  1. public class Test {  
  2.   
  3.     public static void main(String[] args) {  
  4.         String[] strs = {  
  5.                 "abc1232",  "wwwadsf",  
  6.                 "awwwfas",  "wwadfsf",  
  7.                 "", "ww", " ", "www"  
  8.             };  
  9.         String regex = "(?:(?!^www).)*";  
  10.         for(String str : strs) {  
  11.             System.out.printf("%-7s %s%n", str, str.matches(regex));  
  12.         }  
  13.     }  
  14. }  

 

(?!X) 专业名称为 Negative Lookahead,表示字符间缝隙后面不允许出现的字符,
即匹配字符间的缝隙,如果缝隙后的字符不是 X 的话,那这个缝隙就匹配成功。

举个例子,aab 和 aac,现有表达式 aa(?!b) 这时我们能匹配到的字符串是 aac,
因为 aa 的后面的缝隙之后不允许出现字符 b,因此只有 aac 进行了匹配。

再来看个示例:

Java代码
  1. public class Test {  
  2.     public static void main(String[] args) {  
  3.         String str = "AQuickBrownFoxJumpsOverTheLazyDog";  
  4.         String[] strs = str.split("(?
  5.         for(String s : strs) {  
  6.             System.out.println(s);  
  7.         }  
  8.     }  
  9. }