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