Java Matcher.group 方法
上次修改时间:2025 年 4 月 20 日
Matcher.group 方法是 Java 正则表达式 API 中 java.util.regex 包的一部分。 它检索由捕获组在匹配操作期间捕获的输入子序列。 组从左到右编号,从 1 开始。
组 0 始终指整个模式匹配。 group 方法有几个重载,允许通过编号或名称访问组。 此方法对于提取匹配文本的特定部分至关重要。
Matcher.group 方法概述
Matcher.group 方法有三个主要变体。 无参数版本返回整个匹配项(组 0)。 int 版本返回指定的编号组。 String 版本返回一个命名的组。
在调用 group 之前,必须使用 find 或 matches 等方法找到匹配项。 在没有成功匹配的情况下调用 group 将抛出 IllegalStateException。
基本组检索
此示例演示了 Matcher.group 的最简单用法,用于提取匹配的文本。 我们将匹配一个日期模式并提取其组件。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MatcherGroupBasic {
public static void main(String[] args) {
String input = "Today is 2025-04-20";
String regex = "(\\d{4})-(\\d{2})-(\\d{2})";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
System.out.println("Year: " + matcher.group(1));
System.out.println("Month: " + matcher.group(2));
System.out.println("Day: " + matcher.group(3));
}
}
}
在此示例中,我们匹配 YYYY-MM-DD 格式的日期。 正则表达式有三个捕获组,分别用于年、月和日。 group(0) 返回整个匹配项,而 group(1)、group(2) 和 group(3) 返回捕获的组件。
命名组检索
Java 7 引入了命名捕获组,使正则表达式模式更具可读性。 此示例展示了如何将 group 与命名组一起使用。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MatcherGroupNamed {
public static void main(String[] args) {
String input = "Product: Laptop, Price: $999.99";
String regex = "Product: (?<product>\\w+), Price: \\$(?<price>\\d+\\.\\d{2})";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
System.out.println("Product: " + matcher.group("product"));
System.out.println("Price: " + matcher.group("price"));
System.out.println("Full match: " + matcher.group(0));
}
}
}
此示例使用命名组提取产品和价格信息。 (?<name>...) 语法定义命名组。 我们使用 group("product") 和 group("price") 访问这些组。
多组检索
此示例演示了处理多个匹配项及其组。 我们将从文本中提取所有电话号码及其组件。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MatcherGroupMultiple {
public static void main(String[] args) {
String input = "Contacts: 123-456-7890, 555-123-4567, 888-999-0000";
String regex = "(\\d{3})-(\\d{3})-(\\d{4})";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
System.out.println("Full number: " + matcher.group(0));
System.out.println("Area code: " + matcher.group(1));
System.out.println("Exchange: " + matcher.group(2));
System.out.println("Line number: " + matcher.group(3));
System.out.println("-----");
}
}
}
在这里,我们循环处理多个电话号码匹配项。 对于 find 找到的每个匹配项,我们使用 group 提取完整的号码及其组件。 此模式对于处理输入文本中的所有出现非常有用。
可选组处理
正则表达式中的某些组可能是可选的。 此示例展示了在使用 group 时如何安全地处理此类情况。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MatcherGroupOptional {
public static void main(String[] args) {
String[] inputs = {
"Error: 404 - Not Found",
"Error: 500",
"Error: 403 - Forbidden"
};
String regex = "Error: (\\d+)(?: - (.*))?";
Pattern pattern = Pattern.compile(regex);
for (String input : inputs) {
Matcher matcher = pattern.matcher(input);
if (matcher.matches()) {
System.out.println("Code: " + matcher.group(1));
// Check if description group was matched
if (matcher.group(2) != null) {
System.out.println("Description: " + matcher.group(2));
} else {
System.out.println("No description provided");
}
System.out.println("-----");
}
}
}
}
此示例处理描述部分可选的错误消息。 我们使用 matches 进行全字符串匹配,并在访问组 2 之前检查它是否存在。 (?:...) 创建一个非捕获组。
组计数和验证
在访问组之前,最好验证它们是否存在。 此示例展示了如何使用 groupCount 并检查有效组。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MatcherGroupValidation {
public static void main(String[] args) {
String input = "Coordinates: (12.34, 56.78)";
String regex = "\\((\\d+\\.\\d+), (\\d+\\.\\d+)\\)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
System.out.println("Total groups: " + matcher.groupCount());
try {
// Attempt to access a non-existent group
System.out.println("Group 3: " + matcher.group(3));
} catch (IndexOutOfBoundsException e) {
System.out.println("Error: " + e.getMessage());
}
// Safe group access
for (int i = 0; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
}
}
此示例演示了正确的组验证。 groupCount 返回捕获组的数量(不包括组 0)。 我们展示了访问组的错误方式和安全方式,包括错误处理。
高级组替换
组通常用于文本替换操作。 此示例展示了如何在替换字符串中引用组。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MatcherGroupReplacement {
public static void main(String[] args) {
String input = "Name: John Doe, Age: 30, Occupation: Developer";
String regex = "Name: (\\w+ \\w+), Age: (\\d+), Occupation: (\\w+)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.matches()) {
// Reconstruct string using groups
String reconstructed = String.format(
"Occupation: %3$s, Name: %1$s, Age: %2$s",
matcher.group(1), matcher.group(2), matcher.group(3));
System.out.println("Original: " + input);
System.out.println("Reconstructed: " + reconstructed);
// Using replaceAll with group references
String swapped = matcher.replaceAll(
"Age: $2, Name: $1, Job: $3");
System.out.println("Swapped: " + swapped);
}
}
}
此示例展示了两种在替换中使用组的方法。 首先,我们使用 String.format 手动重建字符串。 然后,我们使用 replaceAll 和 $n 组引用。 两种方法都使用捕获组重新排列信息。
嵌套组访问
正则表达式模式可以有嵌套组。 此示例演示了如何访问复杂模式中组内的组。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MatcherGroupNested {
public static void main(String[] args) {
String input = "Version: 2.1.8 (Stable)";
String regex = "Version: ((\\d+)\\.(\\d+)\\.(\\d+)) \\(([A-Za-z]+)\\)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.matches()) {
System.out.println("Full version: " + matcher.group(1));
System.out.println("Major: " + matcher.group(2));
System.out.println("Minor: " + matcher.group(3));
System.out.println("Patch: " + matcher.group(4));
System.out.println("Stability: " + matcher.group(5));
System.out.println("\nGroup numbers:");
for (int i = 0; i <= matcher.groupCount(); i++) {
System.out.println(i + ": " + matcher.group(i));
}
}
}
}
此示例解析带有嵌套组的软件版本字符串。 外层组捕获完整的版本号,而内层组捕获组件。 组号由其开括号的位置分配。
来源
本教程涵盖了 Java Matcher.group 方法的基本方面。 从基本用法到高级技术,理解组对于使用 Java 中的正则表达式进行有效文本处理至关重要。
作者
列出所有Java教程。