Java Matcher.results 方法
上次修改时间:2025 年 4 月 20 日
Matcher.results
方法作为 java.util.regex.Matcher
类的一部分,在 Java 9 中引入。它返回正则表达式模式的匹配结果流。此方法提供了一种现代、函数式的正则表达式匹配方法。
与传统的 find
循环不同,results
能够对匹配结果进行流处理。每个匹配结果都表示为一个 MatchResult
对象。该方法特别适用于以声明式风格处理多个匹配结果。
Matcher.results 概述
results
方法扫描输入序列并返回所有找到的匹配结果。它产生一个 MatchResult
对象流。每个对象包含有关单个匹配结果的信息,包括捕获的组。
该方法是非终结操作,这意味着它不会消耗匹配器。您可以在同一个匹配器上多次调用它。但是,在调用之间,匹配器的状态不能被修改。
Matcher.results() 的基本用法
此示例演示了 results
的最简单用法。我们找到字符串中所有单词的出现并打印它们。流处理使代码简洁易读。
package com.zetcode; import java.util.regex.Pattern; import java.util.regex.Matcher; public class BasicResultsExample { public static void main(String[] args) { String text = "The quick brown fox jumps over the lazy dog"; Pattern pattern = Pattern.compile("\\b\\w{4}\\b"); // 4-letter words Matcher matcher = pattern.matcher(text); matcher.results() .forEach(mr -> System.out.println("Found: " + mr.group())); } }
在这个例子中,我们编译了一个模式来匹配 4 个字母的单词。results
方法返回一个匹配结果流。我们使用 forEach
来打印每个匹配结果。MatchResult
的 group
方法返回匹配的文本。
使用 results 计数匹配结果
results
方法与流操作很好地集成。此示例展示了如何使用流 API 计数匹配结果。这种方法比传统的迭代更简洁。
package com.zetcode; import java.util.regex.Pattern; import java.util.regex.Matcher; public class CountMatchesExample { public static void main(String[] args) { String log = "2023-01-01 INFO Start\n2023-01-01 DEBUG Process\n" + "2023-01-02 ERROR Failed\n2023-01-02 INFO Complete"; Pattern pattern = Pattern.compile("ERROR"); Matcher matcher = pattern.matcher(log); long errorCount = matcher.results().count(); System.out.println("Number of ERROR entries: " + errorCount); } }
在这里,我们搜索日志字符串中的 "ERROR" 条目。results
方法提供了一个可以直接用 count
计数的流。这消除了手动迭代和计数器变量的需要。
提取组信息
MatchResult
对象提供对捕获组的访问。此示例展示了如何从每个匹配结果中提取特定的组信息。我们从字符串中解析日期并以不同的方式格式化它们。
package com.zetcode; import java.util.regex.Pattern; import java.util.regex.Matcher; public class GroupExtractionExample { public static void main(String[] args) { String dates = "2023-05-15, 2024-01-20, 2025-11-30"; Pattern pattern = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})"); Matcher matcher = pattern.matcher(dates); matcher.results() .map(mr -> String.format("Day: %s, Month: %s, Year: %s", mr.group(3), mr.group(2), mr.group(1))) .forEach(System.out::println); } }
此代码匹配日期字符串并提取它们的组成部分。该模式在单独的组中捕获年、月和日。我们使用 map
来重新格式化每个匹配结果,通过它们的索引访问组。结果是重新格式化的日期字符串的流。
过滤和处理匹配结果
流 API 允许对匹配结果进行复杂的处理。此示例根据组内容过滤匹配结果并执行计算。我们找到并求和字符串中的特定数值。
package com.zetcode; import java.util.regex.Pattern; import java.util.regex.Matcher; public class FilterAndSumExample { public static void main(String[] args) { String data = "A=5, B=3, C=8, A=2, B=7, C=1"; Pattern pattern = Pattern.compile("([A-C])=(\\d+)"); Matcher matcher = pattern.matcher(data); int sumA = matcher.results() .filter(mr -> "A".equals(mr.group(1))) .mapToInt(mr -> Integer.parseInt(mr.group(2))) .sum(); System.out.println("Sum of A values: " + sumA); } }
在这里,我们从字符串中提取键值对。我们只过滤 "A" 值,将它们转换为整数,然后将它们求和。results
与流操作的结合创建了一个强大的数据处理管道。
使用 results 的命名捕获组
命名捕获组使模式更具可读性。此示例演示了如何将命名组与 results
一起使用。我们从格式化的字符串中解析用户信息。
package com.zetcode; import java.util.regex.Pattern; import java.util.regex.Matcher; public class NamedGroupsExample { public static void main(String[] args) { String users = "user:john age:30; user:jane age:25"; Pattern pattern = Pattern.compile( "user:(?<name>\\w+)\\s+age:(?<age>\\d+)"); Matcher matcher = pattern.matcher(users); matcher.results() .forEach(mr -> System.out.printf( "User %s is %s years old%n", mr.group("name"), mr.group("age"))); } }
该模式定义了命名组 "name" 和 "age"。我们在 forEach
操作中按名称访问这些组。命名组通过消除组索引的魔术数字,使代码更易于维护。
匹配结果的并行处理
来自 results
的流可以并行处理。此示例展示了如何利用多核处理器进行正则表达式匹配。我们使用并行流操作处理大量文本。
package com.zetcode; import java.util.regex.Pattern; import java.util.regex.Matcher; public class ParallelProcessingExample { public static void main(String[] args) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 100; i++) { sb.append("item").append(i).append(" "); } String largeText = sb.toString(); Pattern pattern = Pattern.compile("item\\d+"); Matcher matcher = pattern.matcher(largeText); long count = matcher.results() .parallel() .count(); System.out.println("Total items found: " + count); } }
我们生成一个包含许多 "itemN" 模式的大字符串。parallel
调用使匹配结果能够并行处理。这可以显着提高大型输入的性能,尽管不能保证顺序。
将 results() 与其他流操作结合使用
results
与完整的 Java 流 API 集成。此示例展示了高级流操作,例如收集到映射。我们构建文本中单词的频率映射。
package com.zetcode; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.stream.Collectors; import java.util.Map; public class StreamOperationsExample { public static void main(String[] args) { String text = "apple banana apple cherry banana apple"; Pattern pattern = Pattern.compile("\\b\\w+\\b"); Matcher matcher = pattern.matcher(text); Map<String, Long> wordCounts = matcher.results() .collect(Collectors.groupingBy( mr -> mr.group().toLowerCase(), Collectors.counting())); System.out.println("Word counts: " + wordCounts); } }
此代码计算字符串中每个单词的出现次数。results
流被收集到一个映射中,其中键是单词,值是计数。这演示了正则表达式匹配如何馈送到复杂的数据处理管道中。
来源
Matcher.results
方法提供了一种在 Java 中进行正则表达式匹配的现代方法。通过返回匹配结果流,它支持函数式风格的处理,这种处理通常比传统迭代更简洁和更具表达力。
作者
列出所有Java教程。