Java MatchResult.group 方法
上次修改时间:2025 年 4 月 20 日
MatchResult.group 方法是 Java 正则表达式 API 的一部分。它返回匹配期间由捕获组捕获的输入子序列。MatchResult 是 Matcher 实现的接口。
捕获组从左到右编号,从 1 开始。组 0 始终指整个匹配项。group 方法有多个重载,可以通过数字或名称访问组。
MatchResult.group 概述
MatchResult 接口提供了查询匹配操作结果的方法。group 方法是访问捕获组的主要方式。它有三种变体。
group 返回整个匹配项(与组 0 相同)。group(int group) 返回按编号指定的组。group(String name) 返回命名组(Java 7+)。
Basic group() 用法
group 最简单的形式返回整个匹配项。这相当于调用 group(0)。当您不需要访问特定的捕获组时,它非常有用。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class BasicGroupExample {
public static void main(String[] args) {
String input = "The quick brown fox jumps over the lazy dog";
String regex = "quick.*fox";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
System.out.println("Full match: " + matcher.group());
System.out.println("Same as group 0: " + matcher.group(0));
}
}
}
在此示例中,我们在输入字符串中搜索模式“quick.*fox”。当我们找到匹配项时,我们使用 group 和 group(0) 打印整个匹配的子序列。
两个调用都返回相同的结果:“quick brown fox”。这表明 group 是访问完整匹配项的便捷简写。
访问编号组
编号的捕获组允许您提取匹配项的特定部分。组从左到右根据它们的左括号进行编号。组 0 始终是整个匹配项。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class NumberedGroupsExample {
public static void main(String[] args) {
String input = "John Doe, age 30, email: john.doe@example.com";
String regex = "(\\w+ \\w+), age (\\d+), email: (\\S+)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
System.out.println("Name: " + matcher.group(1));
System.out.println("Age: " + matcher.group(2));
System.out.println("Email: " + matcher.group(3));
}
}
}
此示例演示如何访问编号的捕获组。正则表达式模式包含三个用括号括起来的捕获组。
组 1 捕获名称,组 2 捕获年龄,组 3 捕获电子邮件。我们使用带有相应组号的 group(int) 访问每个组。
命名捕获组
Java 7 引入了命名捕获组,这使正则表达式模式更具可读性。可以使用 (?<name>...) 语法命名组。可以通过名称访问命名组。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class NamedGroupsExample {
public static void main(String[] args) {
String input = "Date: 2023-04-20, Time: 14:30";
String regex = "Date: (?<date>\\d{4}-\\d{2}-\\d{2}), Time: (?<time>\\d{2}:\\d{2})";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
System.out.println("Full match: " + matcher.group());
System.out.println("Date: " + matcher.group("date"));
System.out.println("Time: " + matcher.group("time"));
// Named groups also have numbers
System.out.println("Date (group 1): " + matcher.group(1));
System.out.println("Time (group 2): " + matcher.group(2));
}
}
}
此示例显示了如何定义和访问命名捕获组。正则表达式包含两个命名组:“date”和“time”。
我们使用 group(String name) 访问这些组。请注意,命名组也具有相应的编号,因此也可以通过编号访问它们。这为您提供了引用捕获组的灵活性。
具有组的多个匹配项
在字符串中处理多个匹配项时,每个匹配项都维护自己的组信息。find 方法前进到下一个匹配项,并相应地更新组信息。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MultipleMatchesExample {
public static void main(String[] args) {
String input = "Product: Laptop, Price: $999.99; Product: Mouse, Price: $49.99";
String regex = "Product: (?<product>\\w+), Price: \\$(?<price>\\d+\\.\\d{2})";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
System.out.println("Product: " + matcher.group("product"));
System.out.println("Price: " + matcher.group("price"));
System.out.println("---");
}
}
}
此示例处理字符串中的多个产品条目。对于 find 找到的每个匹配项,我们可以访问当前匹配项的组。
while 循环持续进行,直到处理完所有匹配项。每次迭代都可以访问该特定匹配项的组。这对于从文本中提取结构化数据非常有用。
处理可选组
正则表达式模式中的某些捕获组可能是可选的。当可选组不参与匹配时,group 会为该组返回 null。在使用可选组时,始终检查 null。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class OptionalGroupsExample {
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.find()) {
System.out.println("Error code: " + matcher.group(1));
String description = matcher.group(2);
if (description != null) {
System.out.println("Description: " + description);
} else {
System.out.println("No description provided");
}
System.out.println("---");
}
}
}
}
此示例演示了处理可选组。正则表达式模式使用 ? 量词使错误描述成为可选的。
对于没有描述的输入,group(2) 返回 null。我们在使用组值之前检查 null。这可以防止在使用模式的可选部分时出现 NullPointerException。
组计数和验证
在访问组之前,最好验证它们的存在。groupCount 方法返回模式中捕获组的数量。请记住,组 0 不包含在此计数中。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class GroupCountExample {
public static void main(String[] args) {
String input = "RGB: (255, 128, 64)";
String regex = "RGB: \\((\\d+), (\\d+), (\\d+)\\)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
System.out.println("Total groups (excluding group 0): " +
matcher.groupCount());
if (matcher.find()) {
for (int i = 0; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
}
}
此示例显示了如何使用 groupCount 来确定有多少个捕获组可用。该模式具有三个用于 RGB 分量的显式组。
我们循环访问所有组(包括组 0)以显示它们的值。了解组计数有助于编写需要处理可变数量组的代码。
高级组提取
对于具有嵌套组的复杂模式,了解组编号至关重要。组根据其左括号的顺序编号,包括嵌套组。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class NestedGroupsExample {
public static void main(String[] args) {
String input = "Coordinates: (40.7128° N, 74.0060° W)";
String regex = "(\\(([\\d.]+)° ([NS]), ([\\d.]+)° ([EW])\\))";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
System.out.println("All parentheses: " + matcher.group(1));
System.out.println("Latitude value: " + matcher.group(2));
System.out.println("Latitude direction: " + matcher.group(3));
System.out.println("Longitude value: " + matcher.group(4));
System.out.println("Longitude direction: " + matcher.group(5));
}
}
}
此示例演示了具有嵌套捕获组的组编号。正则表达式包含多个嵌套级别,用于解析地理坐标。
组 1 捕获外括号中的所有内容。组 2-5 捕获单个组件。在处理复杂模式时,了解此编号至关重要。
来源
在本文中,我们介绍了 MatchResult.group 方法的基本方面。理解捕获组对于在 Java 中使用正则表达式进行有效的文本处理至关重要。
作者
列出所有Java教程。