1:多行匹配

在默认的情况下 . 是不能匹配行结束符的(行结束符有 6 个,具体的可以看看 Pattern 的 API DOC)

同样,可以像不匹配大小写匹配那样使用编译参数:Pattern.DOTALL

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

Java codeimport java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) {
String str =
“
“  
                 \n” + 
 
“    
               \n” + 
 
“       Hello World!    \n” +
“    
              \n” + 
 
“  
                \n” + 
 
“
”; 
 
String regex = “
(.+?)”; 
 
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
while(matcher.find()) {
System.out.println(matcher.group(1).trim());
}
}
}

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

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

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

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

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

当然和 Pattern.CASE_INSENSITIVE 一样,Pattern.DOTALL 也有内嵌标志表达式,即 (?s)

s 的意思表示 single-line 就是忽略换行符什么的,只看成单行进行处理。

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

Java codeString regex = “(?s)
(.+?)”;



如果还要不区分大小写的话,再加上 i 标志:

String regex = “(?s)(?i)
(.+?)”;


但这样显得很拖沓,可以把它们合并起来:

String regex = “(?is)
(.+?)”;    // 秩序无所谓



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

Java codeString regex = “
((.|\\s)+?)”;


这样做是极其危险的,由于选择结构的匹配效率问题,这样做在比较长的字符串时会造成堆栈溢出,

使程序崩溃,如果使用 DOTALL 或者 (?s) 的话就不会出现这种情况。

4:2个单元的或操作

| 称为多选结构,用于匹配 | 之中的任何一个,拿你的例子来说明:

Java codeimport java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) {
String str =
                “
\n” +                “
\n” +                “
”;
        String regex = “”;
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
while(matcher.find()) {
System.out.println(matcher.group());
}
}
}

注意到其中的 (?:ww|3) 在进行多选匹配时尽量找出多选中的规律,以减少多选的字符,

www 和 3w 在最后一个字符可以共用,前面的不一样。

(?: ) 的意思表示组成一组,如果没有 (?: ) 这样的话,表达式就变成了:

Java codeString regex = “”;

这样的语义完全变掉了,| 是在一组中进行选择,由于上面的那个表达式中没有组,就把整个表

达式作为了一组,使用 | 的话,就进行了整个表达式的多选结构了。这个表达式的意思是:

匹配 ,这样的结果并不是我们所要的。

我们仅仅需要在 ww 和 3 之间进行选择,这时只要把 ww 和 3 放在一组中进行多选择就可以了,

变成 (?:ww|3)。

还有,在多选结构中尽量把出现频率高的放在前面,这样可以加快匹配速度。

多选结构的效率在传统型的引擎中是效率低下的,如果是单个字符的选择,比如 a $ & 之中的一个,

那就不要使用 (?:a|$|&) 了,可以直接使用字符类 [a$&] 就可以了。