Java中正則匹配有多種模式,若不選擇模式則默認為單行匹配
匹配模式(Pattern flags)
compile()方法有兩個模式
未開匹配模式
Pattern compile(String regex)
開匹配模式
Pattern compile(String regex, int flags)
源碼關於flags的描述
Match flags, a bit mask that may include
{@link #CASE_INSENSITIVE},
{@link #MULTILINE},
{@link #DOTALL},
{@link #UNICODE_CASE},
{@link #CANON_EQ},
{@link #UNIX_LINES},
{@link #LITERAL},
{@link #UNICODE_CHARACTER_CLASS}
and {@link #COMMENTS}
flags的取值
編譯標志 | 效果 |
---|---|
Pattern.CANON_EQ | 當且僅當兩個字符的"正規分解(canonical decomposition)"都完全相同的情況下,才認定匹配。比如用了這個標志之后,表達式"a/u030A"會匹配"?"。默認情況下,不考慮"規范相等性(canonical equivalence)"。 |
Pattern.CASE_INSENSITIVE (?i) |
默認情況下,大小寫不明感的匹配只適用於US-ASCII字符集。這個標志能讓表達式忽略大小寫進行匹配。要想對Unicode字符進行大小不明感的匹配,只要將UNICODE_CASE與這個標志合起來就行了。 |
Pattern.COMMENTS (?x) |
在這種模式下,匹配時會忽略(正則表達式里的)空格字符(注:不是指表達式里的"//s",而是指表達式里的空格,tab,回車之類)。注釋從#開始,一直到這行結束。可以通過嵌入式的標志來啟用Unix行模式。 |
Pattern.DOTALL (?s) |
在這種模式下,表達式'.'可以匹配任意字符,包括表示一行的結束符。默認情況下,表達式'.'不匹配行的結束符。 |
Pattern.MULTILINE (?m) |
在這種模式下,'^'和'$'分別匹配一行的開始和結束。此外,'^'仍然匹配字符串的開始,'$'也匹配字符串的結束。默認情況下,這兩個表達式僅僅匹配字符串的開始和結束。 |
Pattern.UNICODE_CASE (?u) |
在這個模式下,如果你還啟用了CASE_INSENSITIVE標志,那么它會對Unicode字符進行大小寫不明感的匹配。默認情況下,大小寫不明感的匹配只適用於US-ASCII字符集。 |
Pattern.UNIX_LINES (?d) |
在這個模式下,只有'/n'才被認作一行的中止,並且與'.','^',以及'$'進行匹配。 |
在這些標志里面,Pattern.CASE_INSENSITIVE,Pattern.MULTILINE,以及Pattern.COMMENTS是最有用的(其中Pattern.COMMENTS還能幫我們把思路理清楚,並且/或者做文檔)。注意,你可以用在表達式里插記號的方式來啟用絕大多數的模式。這些記號就在上面那張表的各個標志的下面。你希望模式從哪里開始啟動,就在哪里插記號。
可以用"OR" ('|')運算符把這些標志合使用
下面詳細說明下部分的用法
1、Pattern.MULTILINE模式的用法
正則表達式中出現了^或者$, 默認只會匹配第一行. 設置了Pattern.MULTILINE模式,會匹配所有行。例如:
Pattern p1 = Pattern.compile("^.*b.*$"); //輸出false,因為正則表達式中出現了^或$,默認只會匹配第一行,第二行的b匹配不到。 System.out.println(p1.matcher("a\nb").find()); Pattern p2 = Pattern.compile("^.*b.*$",Pattern.MULTILINE); //輸出true,指定了Pattern.MULTILINE模式,就可以匹配多行了。 System.out.println(p2.matcher("a\nb").find());
2、Pattern.DOTALL模式的用法
默認情況下, 正則表達式中點(.)不會匹配換行符, 設置了Pattern.DOTALL模式, 才會匹配所有字符包括換行符。例如:
Pattern p1 = Pattern.compile("a.*b"); //輸出false,默認點(.)沒有匹配換行符 System.out.println(p1.matcher("a\nb").find()); Pattern p2 = Pattern.compile("a.*b", Pattern.DOTALL); //輸出true,指定Pattern.DOTALL模式,可以匹配換行符。 System.out.println(p2.matcher("a\nb").find());
3、同時指定Pattern.MULTILINE和Pattern.DOTALL模式
實際情況中要是比較復雜的情況,可能Pattern.MULTILINE模式和Pattern.DOTAL模式需要同時指定來匹配多行
Pattern p1 = Pattern.compile("^a.*b$"); //輸出false System.out.println(p1.matcher("cc\na\nb").find()); Pattern p2 = Pattern.compile("^a.*b$", Pattern.DOTALL); //輸出false,因為有^或&沒有匹配到下一行 System.out.println(p2.matcher("cc\na\nb").find()); Pattern p3 = Pattern.compile("^a.*b$", Pattern.MULTILINE); //輸出false,匹配到下一行,但.沒有匹配換行符 System.out.println(p3.matcher("cc\na\nb").find()); //指定多個模式,中間用|隔開 Pattern p4 = Pattern.compile("^a.*b$", Pattern.DOTALL|Pattern.MULTILINE); //輸出true System.out.println(p4.matcher("cc\na\nb").find());
參考: