447. Java 正则表达式 - 内嵌标志表达式

在前面我们介绍了 Pattern Flags,通常通过 Pattern.compile(regex, flags) 来开启模式。其实,还有一种更灵活的写法:把 flag 直接写进正则表达式里,这就是 Embedded Flag Expressions(内嵌标志表达式)


📌 什么是 Embedded Flag Expressions?

语法:

(?flag)regex
  • (?i) → 开启 忽略大小写
  • (?m) → 开启 多行模式
  • (?s) → 开启 DOTALL 模式
  • (?x) → 开启 COMMENTS 模式

⚡ 这种方式的好处是 正则自带“开关”,更直观,也更容易共享或移植。


🔍 示例:(?i) 忽略大小写

String regex = "(?i)foo";  // 内嵌 flag
String input = "FOOfooFoOfoO";

Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);

while (matcher.find()) {
    System.out.println("Found: " + matcher.group());
}

✅ 输出:

Found: FOO
Found: foo
Found: FoO
Found: foO

👉 和 Pattern.CASE_INSENSITIVE 效果一样,但写法更紧凑。


📌 内嵌 flag 对照表

Pattern 常量 内嵌 flag 说明
Pattern.CASE_INSENSITIVE (?i) 忽略大小写
Pattern.COMMENTS (?x) 忽略空格和 # 注释
Pattern.MULTILINE (?m) ^ $ 匹配每一行
Pattern.DOTALL (?s) . 可以匹配换行符
Pattern.UNICODE_CASE (?u) Unicode 下大小写敏感
Pattern.UNIX_LINES (?d) 仅识别 \n 作为换行符
Pattern.CANON_EQ ❌ 无内嵌形式
Pattern.LITERAL ❌ 无内嵌形式

📌 示例:(?m) 多行模式

String regex = "(?m)^dog$";
String input = "dog\ncat\ndog";

Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);

while (m.find()) {
    System.out.println("Match: " + m.group());
}

✅ 输出:

Match: dog
Match: dog

👉 ^dog$ 在多行模式下匹配每行的 "dog",而不是整个文本。


📌 示例:(?s) DOTALL 模式

String regex = "(?s)foo.bar";
String input = "foo\nbar";

System.out.println(Pattern.matches(regex, input)); // true

👉 . 默认不匹配换行,加了 (?s) 就能跨行匹配。


📌 Pattern.matches 静态方法

有时候我们只是想快速判断一个字符串是否匹配某个正则,不需要 Matcher 循环查找。这时可以用:

boolean result = Pattern.matches("\\d", "1");
System.out.println(result); // true

⚠️ 注意:

  • Pattern.matches 会尝试匹配 整个字符串,而不是子串。

  • 等价于:

    Pattern.compile(regex).matcher(input).matches();
    

📌 示例对比:matches() vs find()

Pattern p = Pattern.compile("\\d");
Matcher m = p.matcher("a1b2c3");

System.out.println(m.matches()); // false,因为整个 "a1b2c3" 不是一个数字
m.reset();
while (m.find()) {
    System.out.println("Found: " + m.group());
}
// 输出:1, 2, 3

👉 matches() 要求整串匹配,find() 只要找到子串即可。


🚀 总结

  • 内嵌 flag ((?i), (?m), (?s) …) 让正则更直观,常见于配置文件、脚本中。
  • 外部 flagPattern.compile(regex, flag))更适合在 Java 代码里灵活组合。
  • Pattern.matches 用于快速检查整个字符串是否匹配,find() 用于查找子串。

更多推荐