Java Pattern 类
上次修改时间:2025 年 4 月 20 日
java.util.regex.Pattern
类表示一个已编译的正则表达式。它是 Java 中处理正则表达式的主要类。Pattern 对象是不可变的且线程安全的。
Pattern 提供了静态方法来编译正则表达式并创建 Pattern 对象。编译后,可以使用 Pattern 创建 Matcher 对象来执行匹配操作。该类是 Java 正则表达式包的一部分。
Pattern 类概述
Pattern 是一个 final 类,不能直接实例化。它提供了编译正则表达式模式和执行各种匹配操作的方法。该类与 Matcher 类紧密配合以提供正则表达式功能。
compile
方法创建 Pattern 实例。matcher
方法为模式创建 Matcher。其他方法提供用于模式匹配的实用程序功能。
基本模式匹配
模式匹配允许您确定字符串是否符合特定的正则表达式 (regex) 模式。Pattern.matches
静态方法是进行一次性检查的简单选择,而 Pattern.compile
方法非常适合可重用的正则表达式操作。
package com.zetcode; import java.util.regex.Pattern; public class PatternBasic { public static void main(String[] args) { // Sample input string to be matched String input = "Welcome to Java!"; // Regex pattern to match any string starting with "Welcome" String regex = "Welcome.*"; // Using the static 'matches' method for a quick check boolean isMatch = Pattern.matches(regex, input); System.out.println("Static matches method: " + isMatch); // Compiling the regex pattern for reuse Pattern compiledPattern = Pattern.compile(regex); isMatch = compiledPattern.matcher(input).matches(); System.out.println("Using compiled pattern: " + isMatch); } }
在本例中,我们演示了 Java 中两种模式匹配方法
Pattern.matches
方法是进行不频繁检查的简单选择,因为它在一个步骤中编译和匹配正则表达式。Pattern.compile
方法对于重复匹配更有效,因为它允许您重用已编译的正则表达式。
如果整个输入字符串与正则表达式模式匹配,则两种方法都返回 true
。
探索 Java 中的 Pattern 标志
使用正则表达式 (regex) 时,Pattern 标志在匹配行为方面提供了灵活性。它们可以使匹配不区分大小写,启用多行处理,并引入其他自定义项。标志指定为 Pattern.compile
方法的第二个参数。
package com.zetcode; import java.util.regex.Pattern; public class PatternFlags { public static void main(String[] args) { // Sample input string String input = "Java is powerful\nProgramming is fun!"; // Regex to match a line containing "programming" (case-insensitive) String regex = "^programming.*$"; // Case insensitive matching Pattern caseInsensitive = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); boolean isCaseInsensitiveMatch = caseInsensitive.matcher(input).find(); System.out.println("Case insensitive match: " + isCaseInsensitiveMatch); // Multiline mode (^ and $ match start and end of each line) Pattern multiline = Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); boolean isMultilineMatch = multiline.matcher(input).find(); System.out.println("Multiline match: " + isMultilineMatch); } }
在本例中,我们展示了两个常用的模式标志
CASE_INSENSITIVE
: 使模式匹配过程忽略大小写差异,允许将 "Programming" 和 "programming" 视为相等。MULTILINE
: 调整 ^
和 $
锚点的行为,使它们匹配多行输入中每行的开头和结尾,而不是整个字符串。
可以使用按位 OR 运算符组合这些标志,以创建更多通用的匹配方案。
模式分割
split
方法围绕模式的匹配项分割输入文本。这对于使用复杂分隔符解析文本非常有用。该方法返回一个字符串数组,该数组在模式匹配处被分割。
package com.zetcode; import java.util.regex.Pattern; public class PatternSplit { public static void main(String[] args) { String input = "apple,orange,,banana, grape"; String regex = "\\s*,\\s*"; Pattern pattern = Pattern.compile(regex); String[] fruits = pattern.split(input); System.out.println("Split results:"); for (String fruit : fruits) { System.out.println("'" + fruit + "'"); } // Split with limit String[] limited = pattern.split(input, 3); System.out.println("\nSplit with limit 3:"); for (String fruit : limited) { System.out.println("'" + fruit + "'"); } } }
此示例在逗号处分割字符串,忽略可选的空格。第一个分割处理整个输入。第二个分割使用限制参数来控制最大分割次数。空元素保留在结果中。
模式匹配器操作
matcher
方法创建一个 Matcher 对象,用于执行高级匹配操作。Matcher 提供了诸如 find
、group
和 replaceAll
之类的方法来处理匹配项。
package com.zetcode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class PatternMatcher { public static void main(String[] args) { String input = "Prices: $10.50, $5.25, $8.75"; String regex = "\\$\\d+\\.\\d{2}"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); System.out.println("All prices:"); while (matcher.find()) { System.out.println(matcher.group()); } // Replacement example String result = matcher.replaceAll("PRICE"); System.out.println("\nAfter replacement: " + result); } }
此示例使用 Matcher 在字符串中查找所有美元金额。find
方法定位每个匹配项,而 group
返回匹配的文本。replaceAll
方法将所有匹配项替换为替换字符串。
命名捕获组
Pattern 使用 (?<name>...)
语法支持命名捕获组。命名组使正则表达式模式更具可读性,并且更容易处理匹配项。可以使用组名来检索匹配的内容。
package com.zetcode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class PatternNamedGroups { public static void main(String[] args) { String input = "John Doe, age 30; Jane Smith, age 25"; String regex = "(?<name>[A-Za-z ]+), age (?<age>\\d+)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); while (matcher.find()) { System.out.println("Name: " + matcher.group("name")); System.out.println("Age: " + matcher.group("age")); System.out.println("Full match: " + matcher.group(0) + "\n"); } } }
此示例使用命名组提取姓名和年龄。该模式定义了两个命名组:“name”和“age”。使用名称参数的 group
方法检索匹配的内容。组 0 始终指代完全匹配。
模式引用
quote
静态方法返回输入的字面模式字符串。当您需要匹配可能包含正则表达式元字符的字面字符串时,这很有用。该方法转义所有特殊的正则表达式字符。
package com.zetcode; import java.util.regex.Pattern; public class PatternQuote { public static void main(String[] args) { String input = "File path: C:\\Program Files\\Java"; String literal = "C:\\Program Files\\Java"; // Without quoting (won't work due to special chars) try { boolean matches = Pattern.matches(".*" + literal + ".*", input); System.out.println("Without quote: " + matches); } catch (Exception e) { System.out.println("Error without quote: " + e.getMessage()); } // With quoting String quoted = Pattern.quote(literal); boolean matches = Pattern.matches(".*" + quoted + ".*", input); System.out.println("With quote: " + matches); } }
此示例显示了使用和不使用 quote
的区别。第一次尝试失败,因为反斜杠是正则表达式元字符。引用的版本通过转义字面字符串中的所有特殊字符而正确工作。
模式谓词
Java 11 添加了 asMatchPredicate
和 asPredicate
方法。这些方法将 Pattern 转换为 Predicate,以便与流和其他函数式操作一起使用。谓词测试字符串是否与模式匹配。
package com.zetcode; import java.util.regex.Pattern; import java.util.stream.Stream; public class PatternPredicate { public static void main(String[] args) { Pattern emailPattern = Pattern.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$", Pattern.CASE_INSENSITIVE); Stream.of("user@example.com", "invalid", "another@test.org") .filter(emailPattern.asPredicate()) .forEach(System.out::println); // asMatchPredicate requires full string match System.out.println("\nUsing asMatchPredicate:"); Stream.of("user@example.com", "prefix user@example.com suffix") .filter(emailPattern.asMatchPredicate()) .forEach(System.out::println); } }
此示例演示了两种谓词方法。asPredicate
像 find
一样工作,匹配字符串中的任何位置。asMatchPredicate
像 matches
一样工作,要求整个字符串匹配。两者都适用于过滤流。
来源
在本文中,我们介绍了 Java Pattern 类的基本方法和功能。理解这些概念对于在 Java 应用程序中使用正则表达式至关重要。
作者
列出所有Java教程。