参考: 好文→ Pattern的多种匹配模式 – 《JAVA编程思想》42
目录标题
- 单行匹配
- 多行匹配
- 正则匹配忽略大小写
- Unicode 字符集中的大小写敏感
- 字符都将表示字面含义
- 考虑字符的等价性
- 会忽略正则表达式中的空格及#开始后面的部分
- 只会将 `\n` 认作换行符
- `\w` 可以匹配任何语言的任何字符
单行匹配
Pattern.DOTALL(?s)
:默认匹配模式下 “.
” 不会匹配换行符(\n
),此模式下 ".
"会匹配换行符(\n
),这意味着正则表达式可以在多行文本中进行匹配。
System.out.println(Pattern.compile("[A-Z].*").matcher("ABC\nDEF").matches()); // false
思路引导1. 先看方法是matches,查看是整个字符串都匹配上正则表达式。
思路引导2. [A-Z]开头后面不包含\n就行System.out.println(Pattern.compile("[A-Z].*", Pattern.DOTALL).matcher("ABC\nDEF").matches()); // true
思路引导1. 先看方法是matches,查看是整个字符串都匹配上正则表达式。
思路引导2. [A-Z]开头后面任意Matcher matcher = Pattern.compile("[A-Z].*").matcher("ABC\nDEF");
while (matcher.find()) {System.out.print("," + matcher.group() + "");
}
,ABC,DEF
思路引导1. 先看方法是find,字符串某个部分匹配上正则表达式即可。
思路引导2. [A-Z]开头后面不包含\n就行
多行匹配
Pattern.MULTILINE(?m)
:多行模式并不改变.
的行为,而是影响 ^
和 $
的行为。在默认情况下,^
和 $
分别匹配字符串的开始和结束。但在多行模式下,^
和 $
还可以分别匹配每行的开始和结束。如果需要仅匹配字符串开始和结束位置,可以使用 \A
和 \Z
。
System.out.println(Pattern.compile(".*BC").matcher("AB\nBC").find()); // trueSystem.out.println(Pattern.compile("^.*BC$").matcher("AB\nBC").find()); // false
思路引导1.^$+find等价于matchs,查看是整个字符串都匹配上正则表达式。
思路引导2.前面谁都行就是不能为\n
System.out.println(Pattern.compile("^.*BC$").matcher("AB\nBC").matches()); // falseMatcher m2 = Pattern.compile("^.*BC$", Pattern.MULTILINE).matcher("AB\nBC");
if (m2.find()) {System.out.println(m2.group()); // BC
}Matcher m3 = Pattern.compile("\\A.*BC\\Z", Pattern.MULTILINE).matcher("AB\nBC");
if (m3.find()) {System.out.println(m3.group()); // 没匹配到
}
正则匹配忽略大小写
Pattern.CASE_INSENSITIVE(?i)
:此模式下进行匹配会忽略 US-ASCII
字符集中的大小写敏感,若需要忽略 Unicode
中的大小写敏感,需要结合 Pattern.UNICODE_CASE
使用。
// 忽略 Unicode 中的大小写敏感
System.out.println(Pattern.compile("[A-Z]+", Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE).matcher("abc").matches()); // true
System.out.println(Pattern.compile("(?i)|(?u)[A-Z]+").matcher("abc").matches()); // true// 忽略 US-ASCII字符集中的大小写敏感
System.out.println(Pattern.compile("[A-Z]+", Pattern.CASE_INSENSITIVE).matcher("abc").matches()); // true
System.out.println(Pattern.compile("(?i)[A-Z]+").matcher("abc").matches()); // true
Unicode 字符集中的大小写敏感
Pattern.CASE_INSENSITIVE (?u)
:
字符都将表示字面含义
Pattern.LITERAL
:此模式下所有的转义字符或元字符都将表示字面含义,不代表任何特殊意义
System.out.println(Pattern.compile("\\s").matcher("\\s").matches()); // false
System.out.println(Pattern.compile("\\s", Pattern.LITERAL).matcher("\\s").matches()); // true
考虑字符的等价性
Pattern.CANON_EQ
:此模式下进行匹配会考虑字符的等价性。
例如:正则表达式 \u003f
会匹配字符 ?
, 因为 ?
的 unicode 编码就是 \u003f
。
System.out.println(Pattern.compile("\\u003f", Pattern.CANON_EQ).matcher("?").matches()); // true
会忽略正则表达式中的空格及#开始后面的部分
Pattern.COMMENTS(?x)
:
Pattern p1 = Pattern.compile("#[A-Z]+");
System.out.println(p1.matcher("#ABC").matches());
Pattern p2 = Pattern.compile("#[A-Z]+", Pattern.COMMENTS);
System.out.println(p2.matcher("#ABC").matches());
Pattern p3 = Pattern.compile("[0-9]+#[A-Z]+", Pattern.COMMENTS);
System.out.println(p3.matcher("123").matches());
Pattern p4 = Pattern.compile("[A-Z]+ [0-9]+");
System.out.println(p4.matcher("ABC123").matches());
Pattern p5 = Pattern.compile("[A-Z]+ [0-9]+", Pattern.COMMENTS);
System.out.println(p5.matcher("ABC123").matches());
只会将 \n
认作换行符
Pattern.UNIX_LINES(?d)
:在此模式下进行匹配,在 .
、^
、$
三种行为中,只会将 \n
认作换行符,默认模式下会将 \r
也认作换行符。
String data = "A\r\nB\rC\nD";
System.out.println(data);
System.out.println("-------------------------------------");Matcher m = Pattern.compile(".+").matcher(data);
while (m.find()) {System.out.println("[" + m.group() + "]"); // [A][B][C][D]
}
System.out.println("-------------------------------------");m = Pattern.compile(".+", Pattern.UNIX_LINES).matcher(data);
while (m.find()) {System.out.println("[" + m.group() + "]"); // (A\r)、(B\rC)、(D)
}
\w
可以匹配任何语言的任何字符
Pattern.UNICODE_CHARACTER_CLASS (?U)
:\w 默认只匹配[a-zA-Z_0-9]
开启此模式后,\w 可以匹配任何语言的任何字符。
Pattern p1 = Pattern.compile("\\w+");
System.out.println(p1.matcher("中国").matches());Pattern p2 = Pattern.compile("\\w+", Pattern.UNICODE_CHARACTER_CLASS);
System.out.println(p2.matcher("中国").matches());