Java Pattern.compile 方法
上次修改时间:2025 年 4 月 20 日
Pattern.compile 方法是 Java 中创建 Pattern 对象的主要方式。它将给定的正则表达式编译成一个模式,可用于匹配操作。编译后的模式是不可变的并且是线程安全的。
Pattern.compile 有两个主要变体:一个只接受正则表达式字符串,另一个接受正则表达式标志。这些标志修改模式匹配的行为。该方法对无效的正则表达式抛出 PatternSyntaxException 异常。
基本模式编译
Pattern.compile 最简单的形式接受单个正则表达式字符串参数。这将创建一个具有默认匹配行为的 Pattern 对象。然后,编译后的模式可以用于创建 Matcher 对象或执行直接匹配。
package com.zetcode;
import java.util.regex.Pattern;
public class BasicCompile {
public static void main(String[] args) {
// Simple regex to match words starting with 'J'
String regex = "\\bJ\\w+\\b";
String input = "Java JavaScript Python Ruby";
// Compile the pattern
Pattern pattern = Pattern.compile(regex);
// Use the pattern to find matches
boolean hasMatch = pattern.matcher(input).find();
System.out.println("Found match: " + hasMatch);
// Count matches
long matchCount = pattern.matcher(input).results().count();
System.out.println("Match count: " + matchCount);
}
}
此示例演示了基本模式编译和用法。正则表达式匹配以 'J' 开头的单词。我们编译它一次,并在查找和计数匹配项时重复使用它。Pattern 对象是线程安全的,并且可以有效地重复使用。
使用标志编译
Pattern.compile 可以接受修改匹配行为的标志。常见的标志包括 CASE_INSENSITIVE、MULTILINE 和 DOTALL。标志作为第二个参数指定,使用按位或运算符来组合多个标志。
package com.zetcode;
import java.util.regex.Pattern;
public class CompileWithFlags {
public static void main(String[] args) {
String regex = "^[a-z]+$"; // Only lowercase letters
String input = "HELLO\nworld\nJAVA";
// Case insensitive matching
Pattern caseInsensitive = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
// Multiline mode (^ and $ match start/end of lines)
Pattern multiline = Pattern.compile(regex,
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
System.out.println("Case insensitive matches:");
caseInsensitive.matcher(input).results()
.forEach(mr -> System.out.println(mr.group()));
System.out.println("\nMultiline matches:");
multiline.matcher(input).results()
.forEach(mr -> System.out.println(mr.group()));
}
}
此示例演示了标志的用法。第一个模式不区分大小写地匹配,但只找到一个匹配项。第二个模式添加了 MULTILINE 标志,使 ^ 和 $ 在行边界处匹配。这会找到符合条件的每行匹配项。
模式拆分
编译后的模式可以使用 split 方法拆分字符串。这比 String.split 更强大,因为它允许重用编译后的模式。该方法接受一个输入字符串和可选的 limit 参数。
package com.zetcode;
import java.util.regex.Pattern;
public class PatternSplitExample {
public static void main(String[] args) {
// Complex delimiter: comma with optional whitespace
String regex = "\\s*,\\s*";
String input = "apple, orange,banana,,grape";
Pattern pattern = Pattern.compile(regex);
// Split without limit
String[] fruits = pattern.split(input);
System.out.println("All fruits:");
for (String fruit : fruits) {
System.out.println("'" + fruit + "'");
}
// Split with limit (max 3 parts)
String[] limited = pattern.split(input, 3);
System.out.println("\nLimited split:");
for (String fruit : limited) {
System.out.println("'" + fruit + "'");
}
}
}
此示例演示了模式拆分。正则表达式处理带可选空格的逗号。第一个拆分处理整个字符串。第二个拆分将结果限制为 3 部分,其余部分不拆分。包含空元素。
使用分组进行模式匹配
编译后的模式可以使用括号捕获分组。分组允许提取匹配项的特定部分。组 0 是整个匹配项,而组 1+ 是捕获的子组。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternGroups {
public static void main(String[] args) {
// Pattern with capturing groups
String regex = "(\\d{2})-(\\d{2})-(\\d{4})";
String input = "Date: 12-31-2023, Another: 01-15-2024";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
System.out.println("Month: " + matcher.group(1));
System.out.println("Day: " + matcher.group(2));
System.out.println("Year: " + matcher.group(3));
System.out.println();
}
}
}
此示例使用分组提取日期组件。该模式将月、日和年捕获为单独的组。Matcher 的 group 方法检索每个捕获的组。组按其左括号从左到右编号。
命名捕获组
Java 7+ 支持命名捕获组,以获得更具可读性的代码。组使用 (?<name>regex) 语法命名。可以使用名称而不是数字来检索匹配的内容。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class NamedGroupsExample {
public static void main(String[] args) {
// Pattern with named groups
String regex = "(?<area>\\d{3})-(?<exchange>\\d{3})-(?<line>\\d{4})";
String input = "Phone: 123-456-7890, Fax: 987-654-3210";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
System.out.println("Full number: " + matcher.group(0));
System.out.println("Area code: " + matcher.group("area"));
System.out.println("Exchange: " + matcher.group("exchange"));
System.out.println("Line number: " + matcher.group("line"));
System.out.println();
}
}
}
此示例使用命名组来解析电话号码。号码的每个部分都有一个描述性名称。group 方法接受数字或名称。命名组使模式更易于维护,代码更具可读性。
Pattern Quote 方法
Pattern.quote 方法返回一个字面模式字符串。这将转义输入中所有特殊的正则表达式字符。当匹配可能包含正则表达式元字符的字面字符串时,它非常有用。
package com.zetcode;
import java.util.regex.Pattern;
public class PatternQuoteExample {
public static void main(String[] args) {
String searchString = "file.(txt)";
String input = "Looking for file.(txt) in directory";
// Without quoting - fails because parentheses are special
try {
Pattern badPattern = Pattern.compile(searchString);
System.out.println("Unquoted match: " +
badPattern.matcher(input).find());
} catch (Exception e) {
System.out.println("Unquoted pattern failed: " + e.getMessage());
}
// With quoting - works correctly
String quoted = Pattern.quote(searchString);
Pattern goodPattern = Pattern.compile(quoted);
System.out.println("Quoted match: " +
goodPattern.matcher(input).find());
}
}
此示例显示了引用的重要性。第一次尝试失败,因为括号是正则表达式元字符。引用的版本转义了所有特殊字符,允许精确的字面匹配。始终对用户输入使用引用。
Pattern 谓词
Java 11 向 Pattern 添加了 asPredicate 和 asMatchPredicate 方法。这些将模式转换为用于函数式编程的 Predicate。asPredicate 的行为类似于 find,而 asMatchPredicate 的行为类似于 matches。
package com.zetcode;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public class PatternPredicateExample {
public static void main(String[] args) {
// Email validation pattern
String regex = "^[\\w.-]+@[\\w.-]+\\.[a-z]{2,}$";
Pattern emailPattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
Stream.of("user@example.com", "invalid.email", "admin@test.org")
.filter(emailPattern.asPredicate())
.forEach(System.out::println);
System.out.println("\nWith asMatchPredicate:");
Stream.of("user@example.com", "prefix user@example.com suffix")
.filter(emailPattern.asMatchPredicate())
.forEach(System.out::println);
}
}
此示例演示了模式谓词的实际应用。asPredicate 过滤包含电子邮件地址的字符串。asMatchPredicate 更严格,要求整个字符串是一个电子邮件。两者都对流操作和过滤很有用。
来源
本教程涵盖了 Java 中 Pattern.compile 的基本方面。从基本编译到高级功能,如命名组和谓词,这些示例演示了该方法在正则表达式处理中的多功能性。
作者
列出所有Java教程。