Java Matcher.toMatchResult 方法
上次修改时间:2025 年 4 月 20 日
Java 中的 Matcher.toMatchResult 方法返回当前匹配状态的快照,作为 MatchResult 对象。 这允许您捕获和检查匹配信息,而不会影响匹配器的状态。
MatchResult 接口提供了访问匹配详细信息(如组内容和位置)的方法。 当您需要保留匹配信息以供以后处理或与多个线程一起工作时,这非常有用。
Matcher.toMatchResult 概述
toMatchResult 方法创建当前匹配状态的不可变快照。 返回的 MatchResult 包含有关匹配的所有信息,包括组及其位置。
当您需要存储匹配结果或将其传递给其他方法时,此方法特别有用。 即使原始匹配器继续匹配操作,快照仍然有效。
toMatchResult 的基本用法
此示例演示了 toMatchResult 的基本用法来捕获匹配信息。 我们将从一个简单的模式匹配中提取细节。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.MatchResult;
public class BasicMatchResult {
public static void main(String[] args) {
String input = "The quick brown fox jumps over the lazy dog";
String regex = "(quick) (brown) (fox)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
MatchResult result = matcher.toMatchResult();
System.out.println("Full match: " + result.group());
System.out.println("Group 1: " + result.group(1));
System.out.println("Group 2: " + result.group(2));
System.out.println("Group 3: " + result.group(3));
System.out.println("Match start: " + result.start());
System.out.println("Match end: " + result.end());
}
}
}
在此示例中,我们创建一个带有三个捕获组的模式。 找到匹配项后,我们使用 toMatchResult 来捕获匹配状态。
MatchResult 对象提供对匹配文本及其在输入字符串中的位置的访问权限。 我们可以使用 group 方法检索完整的匹配项和各个组。
多个匹配快照
此示例演示了如何在匹配操作期间捕获多个匹配状态。 我们将每个匹配结果存储在一个列表中,以供以后处理。
package com.zetcode;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.MatchResult;
public class MultipleMatchResults {
public static void main(String[] args) {
String input = "John:30, Jane:25, Bob:40, Alice:35";
String regex = "(\\w+):(\\d+)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
List<MatchResult> results = new ArrayList<>();
while (matcher.find()) {
results.add(matcher.toMatchResult());
}
System.out.println("Captured matches:");
for (MatchResult result : results) {
System.out.printf("Name: %s, Age: %s%n",
result.group(1), result.group(2));
}
}
}
在这里,我们处理包含名称-年龄对的字符串。 对于找到的每个匹配项,我们使用 toMatchResult 存储匹配状态。
存储的 MatchResult 对象允许我们稍后处理匹配项,即使在匹配器继续其操作之后也是如此。 这对于匹配结果的批处理非常有用。
线程安全的匹配结果
此示例演示了如何使用 toMatchResult 创建线程安全的匹配结果。 可以安全地将快照传递给另一个线程。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.MatchResult;
public class ThreadSafeMatchResult {
public static void main(String[] args) {
String input = "Server1:192.168.1.1, Server2:192.168.1.2";
String regex = "(Server\\d+):(\\d+\\.\\d+\\.\\d+\\.\\d+)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
MatchResult result = matcher.toMatchResult();
new Thread(() -> {
System.out.printf("Processing %s at %s in thread %s%n",
result.group(1), result.group(2),
Thread.currentThread().getName());
}).start();
}
}
}
在此示例中,我们为每个匹配结果创建一个新线程。 MatchResult 快照安全地传递给每个线程。
如果没有 toMatchResult,在线程之间共享匹配器状态将是不安全的。 不可变的快照确保对匹配结果的线程安全访问。
带组的匹配结果
此示例演示了如何使用 toMatchResult 处理捕获的组。 我们将从一个复杂的模式中提取结构化数据。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.MatchResult;
public class GroupMatchResult {
public static void main(String[] args) {
String input = "Date: 2023-04-20, Time: 14:30, Location: Room 101";
String regex = "Date: (?<date>\\d{4}-\\d{2}-\\d{2}), " +
"Time: (?<time>\\d{2}:\\d{2}), " +
"Location: (?<location>[A-Za-z0-9 ]+)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
MatchResult result = matcher.toMatchResult();
System.out.println("Full match: " + result.group());
System.out.println("Date: " + result.group("date"));
System.out.println("Time: " + result.group("time"));
System.out.println("Location: " + result.group("location"));
System.out.println("Group count: " + result.groupCount());
}
}
}
在这里,我们使用命名捕获组从字符串中提取结构化信息。 MatchResult 提供对编号组和命名组的访问。
该示例演示了 toMatchResult 如何保留所有组信息,使其可供以后使用。 组计数包括模式中的所有捕获组。
匹配位置信息
此示例侧重于从 MatchResult 检索匹配位置信息。 我们将检查匹配项的开始和结束位置。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.MatchResult;
public class PositionMatchResult {
public static void main(String[] args) {
String input = "The rain in Spain falls mainly on the plain";
String regex = "\\b\\w{4}\\b"; // 4-letter words
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
MatchResult result = matcher.toMatchResult();
System.out.printf("Word '%s' found at [%d,%d)%n",
result.group(),
result.start(),
result.end());
System.out.println("Surrounding text: '" +
input.substring(Math.max(0, result.start() - 3),
Math.min(input.length(), result.end() + 3)) +
"'");
}
}
}
此代码查找字符串中的所有 4 个字母的单词并捕获它们的位置。 MatchResult 提供精确的位置信息。
我们使用位置数据来提取每个匹配项周围的文本。 这演示了位置信息如何对匹配项的上下文感知处理非常有用。
重用匹配结果
此示例演示了如何在程序中存储和重用匹配结果。 我们将在匹配操作完成后处理结果。
package com.zetcode;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.MatchResult;
public class ReuseMatchResult {
public static void main(String[] args) {
String input = "Product1: $10.99, Product2: $20.50, Product3: $5.75";
String regex = "Product(\\d+): \\$(\\d+\\.\\d{2})";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
List<MatchResult> results = new ArrayList<>();
while (matcher.find()) {
results.add(matcher.toMatchResult());
}
// Process results later
System.out.println("Product Report:");
double total = 0;
for (MatchResult result : results) {
String product = result.group(1);
double price = Double.parseDouble(result.group(2));
total += price;
System.out.printf("Product %s: $%.2f%n", product, price);
}
System.out.printf("Total value: $%.2f%n", total);
}
}
在此示例中,我们先存储所有匹配结果,然后再处理它们。 这允许我们将程序的匹配阶段和处理阶段分开。
MatchResult 对象保留所有匹配信息,从而可以在初始匹配完成后进行复杂处理。 此模式对于批处理场景非常有用。
高级 MatchResult 分析
最后一个示例演示了使用多个 MatchResult 对象的高级分析。 我们将比较匹配项并提取关系。
package com.zetcode;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.MatchResult;
public class AdvancedMatchResult {
public static void main(String[] args) {
String input = "user1:file1.txt, user2:file2.doc, user1:file3.pdf, user3:file1.txt";
String regex = "(\\w+):(\\w+\\.\\w+)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
Map<String, Integer> userFileCounts = new HashMap<>();
Map<String, Integer> fileUserCounts = new HashMap<>();
while (matcher.find()) {
MatchResult result = matcher.toMatchResult();
String user = result.group(1);
String file = result.group(2);
userFileCounts.put(user, userFileCounts.getOrDefault(user, 0) + 1);
fileUserCounts.put(file, fileUserCounts.getOrDefault(file, 0) + 1);
}
System.out.println("Files per user:");
userFileCounts.forEach((user, count) ->
System.out.printf("%s: %d files%n", user, count));
System.out.println("\nUsers per file:");
fileUserCounts.forEach((file, count) ->
System.out.printf("%s: %d users%n", file, count));
}
}
此代码分析字符串中用户和文件之间的关系。 我们使用 toMatchResult 捕获每个匹配项并构建统计图。
该示例展示了如何将 MatchResult 对象用于超出简单匹配的复杂分析。 即使在匹配器移动后,不可变的快照也能实现可靠的数据处理。
来源
在本文中,我们探讨了 Matcher.toMatchResult 方法及其各种应用。 这项强大的功能可以在 Java 正则表达式处理中实现高级匹配处理和线程安全操作。
作者
列出所有Java教程。