在 Java 21 中,正则表达式主要通过 java.util.regex
包提供支持,其核心组件包括 Pattern
、Matcher
和 String
类中自带的方法(如 replaceAll
和 matches
)。以下是关于正则表达式在 Java 21 中的详细介绍及一些新的特性或用法。
核心组件
1. Pattern
类
Pattern
是正则表达式的编译表示形式。- 使用
Pattern.compile(String regex)
编译正则表达式。 - 提供了优化匹配的标志位(如
CASE_INSENSITIVE
、DOTALL
)。
Pattern pattern = Pattern.compile("[a-z]+", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher("Hello World");
while (matcher.find()) {
System.out.println(matcher.group()); // 输出 "Hello" 和 "World"
}
2. Matcher
类
Matcher
是执行匹配操作的引擎,依赖于Pattern
。- 支持多种匹配方式:
find()
、matches()
、lookingAt()
等。
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher("Order 123, Item 456");
while (matcher.find()) {
System.out.println(matcher.group()); // 输出 123 和 456
}
3. String
中的正则方法
matches
:检查整个字符串是否匹配正则表达式。replaceAll
和replaceFirst
:使用正则表达式进行替换。split
:使用正则表达式分割字符串。
String str = "apple,banana,orange";
String[] fruits = str.split(",");
for (String fruit : fruits) {
System.out.println(fruit);
}
常见标志和特性
常用标志位(Pattern
常量)
标志位 | 含义 |
---|---|
Pattern.CASE_INSENSITIVE | 忽略大小写匹配(等价于 (?i) )。 |
Pattern.MULTILINE | 允许 ^ 和 $ 匹配每行的开头和结尾(等价于 (?m) )。 |
Pattern.DOTALL | 使 . 匹配包括换行符在内的所有字符(等价于 (?s) )。 |
Pattern.UNICODE_CASE | 结合 CASE_INSENSITIVE ,对 Unicode 字符有效。 |
Pattern.COMMENTS | 忽略正则中的空白和注释(等价于 (?x) )。 |
Pattern pattern = Pattern.compile("^hello", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
Matcher matcher = pattern.matcher("hello world\nHello Java");
while (matcher.find()) {
System.out.println(matcher.group()); // 输出 "hello" 和 "Hello"
}
正则表达式语法
基础元字符
元字符 | 含义 |
---|---|
. | 匹配任意单个字符(除换行符)。 |
\d | 匹配数字(0-9)。 |
\w | 匹配字母、数字或下划线。 |
\s | 匹配空白字符(空格、制表符等)。 |
\b | 匹配单词边界。 |
^ | 匹配行的开头。 |
$ | 匹配行的结尾。 |
[...] | 匹配括号内任意一个字符。 |
[^...] | 匹配括号内没有的任意字符。 |
Pattern pattern = Pattern.compile("\\d{3}-\\d{2}-\\d{4}");
Matcher matcher = pattern.matcher("123-45-6789");
if (matcher.matches()) {
System.out.println("Valid format!"); // 输出 "Valid format!"
}
高级语法
表达式 | 含义 |
---|---|
(...) | 分组,捕获子表达式。 |
(?:...) | 非捕获分组。 |
(?=...) | 正向先行断言(匹配后面紧跟的内容)。 |
(?!...) | 负向先行断言(匹配后面不紧跟的内容)。 |
(?<=...) | 正向后行断言(匹配前面紧跟的内容)。 |
(?<!...) | 负向后行断言(匹配前面不紧跟的内容)。 |
// 示例:正向先行断言
Pattern pattern = Pattern.compile("\\d+(?= dollars)");
Matcher matcher = pattern.matcher("I owe 100 dollars");
if (matcher.find()) {
System.out.println(matcher.group()); // 输出 "100"
}
Java 21 中的新特性
-
Unicode 支持增强
- Java 21 继续支持最新版本的 Unicode,正则表达式对 Unicode 的处理更加全面。
- 例如,
\p{Script=Latin}
匹配所有拉丁字符。
-
更高的性能优化
Pattern
的编译器在 Java 21 中进一步优化,能够处理更复杂的正则表达式并提供更快的匹配速度。
-
内置内联正则表达式语法改进
- 可以直接将常用标志(如
CASE_INSENSITIVE
、DOTALL
)内嵌在正则表达式中,无需额外设置。
- 可以直接将常用标志(如
实践示例
验证邮箱
Pattern pattern = Pattern.compile("^[\\w.%+-]+@[\\w.-]+\\.[a-zA-Z]{2,}$");
Matcher matcher = pattern.matcher("example@example.com");
System.out.println(matcher.matches()); // 输出 true
替换多行文本
String text = "<tag>\nSome content\n</tag>";
String result = text.replaceAll("(?s)<.*?>", "REPLACED");
System.out.println(result); // 输出 REPLACED
提取 URL 中的域名
Pattern pattern = Pattern.compile("https?://([^/]+)");
Matcher matcher = pattern.matcher("https://www.example.com/path");
if (matcher.find()) {
System.out.println(matcher.group(1)); // 输出 www.example.com
}
总结
在 Java 21 中,正则表达式依然强大,支持 Unicode、标志位、断言等多种高级特性。借助 Pattern
和 Matcher
,你可以高效地处理复杂的文本匹配需求。此外,性能优化和更广泛的 Unicode 支持让正则表达式在 Java 21 中更加灵活和高效。