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教程。