Java MatchResult.groupCount 方法
上次修改时间:2025 年 4 月 20 日
MatchResult.groupCount
方法返回正则表达式模式中捕获组的数量。 它是 java.util.regex.MatchResult
接口的一部分。 此方法对于处理使用组的复杂正则表达式模式至关重要。
捕获组是正则表达式模式中用括号括起来的部分。 它们允许您提取匹配文本的特定部分。 groupCount
方法有助于确定模式中存在多少个这样的组。
MatchResult.groupCount 概述
groupCount
方法返回一个整数,表示模式中捕获组的数量。 此计数不包括特殊组 0,它始终表示整个匹配项。 该方法在 Matcher 对象和其他实现 MatchResult 的类上可用。
理解组计数在处理匹配项时至关重要,因为它有助于您了解可以访问多少个组。 可以使用索引从 1 到 groupCount() 的 group(int)
方法检索每个组。
基本 groupCount 示例
此示例演示了 groupCount
的基本用法,其中包含一个包含两个捕获组的简单模式。 我们将看到如何访问组计数和单个组。
package com.zetcode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class BasicGroupCount { public static void main(String[] args) { String input = "John Doe, age 30"; String regex = "(\\w+) (\\w+), age (\\d+)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); if (matcher.find()) { System.out.println("Total groups: " + matcher.groupCount()); System.out.println("Full match: " + matcher.group(0)); System.out.println("First name: " + matcher.group(1)); System.out.println("Last name: " + matcher.group(2)); System.out.println("Age: " + matcher.group(3)); } } }
在此示例中,我们创建一个包含三个捕获组的模式。 groupCount
方法返回 3,与我们的三个带括号的组匹配。 然后,我们使用其索引 (1-3) 访问每个组,并使用索引 0 访问完整匹配项。
输出显示组 0 包含整个匹配项,而组 1-3 包含捕获的子字符串。 这演示了 groupCount
如何帮助浏览捕获的组。
groupCount 与嵌套组
此示例显示了 groupCount
如何与嵌套捕获组一起使用。 嵌套组会使模式更加复杂,但 groupCount
仍然可以准确地报告总数。
package com.zetcode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class NestedGroups { public static void main(String[] args) { String input = "2023-05-15"; String regex = "((\\d{4})-(\\d{2})-(\\d{2}))"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); if (matcher.find()) { System.out.println("Total groups: " + matcher.groupCount()); System.out.println("Full match: " + matcher.group(0)); System.out.println("Outer group: " + matcher.group(1)); System.out.println("Year: " + matcher.group(2)); System.out.println("Month: " + matcher.group(3)); System.out.println("Day: " + matcher.group(4)); } } }
这里我们有一个带有嵌套组的日期模式。 外部组捕获整个日期,而内部组分别捕获年、月和日。 groupCount
返回 4,计算所有捕获组。
请注意,组 1 包含完整日期(与组 0 相同),而组 2-4 包含各个组件。 这表明嵌套组是如何从左到右按顺序计数的。
groupCount 与非捕获组
此示例演示了非捕获组(使用 (?:...)
)如何影响组计数。 非捕获组对于应用量词而不创建捕获组非常有用。
package com.zetcode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class NonCapturingGroups { public static void main(String[] args) { String input = "color or colour"; String regex = "col(o?:u)r"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); while (matcher.find()) { System.out.println("\nMatch: " + matcher.group(0)); System.out.println("Total groups: " + matcher.groupCount()); System.out.println("Group 1: " + matcher.group(1)); } } }
在此模式中,我们有一个捕获组和一个非捕获组。 groupCount
返回 1,因为仅计算显式捕获组。 非捕获组不会增加计数。
输出显示,尽管模式中有两个带括号的表达式,但只有一个被计数并通过 group(1)
访问。 这演示了在不需要捕获时如何优化模式。
groupCount 与命名组
Java 支持使用 (?<name>...)
语法命名捕获组。 此示例显示了命名组如何影响 groupCount
以及如何访问它们。
package com.zetcode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class NamedGroups { 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("Total groups: " + matcher.groupCount()); System.out.println("Full match: " + matcher.group(0)); System.out.println("Product (by name): " + matcher.group("product")); System.out.println("Product (by index): " + matcher.group(1)); System.out.println("Price (by name): " + matcher.group("price")); System.out.println("Price (by index): " + matcher.group(2)); } } }
此示例使用两个命名组:“product”和“price”。 groupCount
返回 2,因为命名组仍然像往常一样计数。 可以通过名称或数字索引访问它们。
命名组使模式更具可读性和可维护性,尤其是在复杂模式下。 无论组是否命名,groupCount
方法的工作方式都相同。
groupCount 与零组
此示例显示了当模式没有捕获组时 groupCount
的行为。 它有助于理解组计数的基线情况。
package com.zetcode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ZeroGroups { public static void main(String[] args) { String input = "Simple text matching"; String regex = "[A-Za-z ]+"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); if (matcher.find()) { System.out.println("Total groups: " + matcher.groupCount()); System.out.println("Full match: " + matcher.group(0)); // Attempting to access group 1 would throw IndexOutOfBoundsException try { System.out.println("Group 1: " + matcher.group(1)); } catch (IndexOutOfBoundsException e) { System.out.println("Cannot access group 1: " + e.getMessage()); } } } }
这里我们有一个没有捕获组的模式。 groupCount
方法返回 0,表示除了组 0(完整匹配)之外,没有其他组可以访问。 尝试访问组 1 会引发异常。
这表明 groupCount
准确地反映了模式何时没有捕获组。 在通过索引访问组之前,检查此项始终是安全的。
groupCount 与交替
此示例探讨了交替(使用 | 运算符)如何影响组计数。 我们将看到交替的不同分支如何具有不同数量的组。
package com.zetcode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class AlternationGroups { public static void main(String[] args) { String input1 = "Date: 2023-05-15"; String input2 = "Timestamp: 202305151200"; String regex = "(Date: (\\d{4}-\\d{2}-\\d{2}))|(Timestamp: (\\d{12}))"; Pattern pattern = Pattern.compile(regex); // Test first pattern branch Matcher matcher1 = pattern.matcher(input1); if (matcher1.find()) { System.out.println("Input1 groups: " + matcher1.groupCount()); System.out.println("Full match: " + matcher1.group(0)); System.out.println("Date group: " + matcher1.group(1)); System.out.println("Date value: " + matcher1.group(2)); } // Test second pattern branch Matcher matcher2 = pattern.matcher(input2); if (matcher2.find()) { System.out.println("\nInput2 groups: " + matcher2.groupCount()); System.out.println("Full match: " + matcher2.group(0)); System.out.println("Timestamp group: " + matcher2.group(3)); System.out.println("Timestamp value: " + matcher2.group(4)); } } }
此模式具有交替,每个分支中的组数不同。 groupCount
返回 4,表示整个模式中捕获组的总数,无论哪个分支匹配。
当第一个分支匹配时,组 1 和 2 包含值,而组 3 和 4 为 null。 相反,当第二个分支匹配时,组 3 和 4 包含值。 这显示了 groupCount
如何报告最大可能的组数。
groupCount 在替换操作中
最后一个示例演示了在字符串替换操作的上下文中使用 groupCount
。 我们将看到组计数如何影响替换模式。
package com.zetcode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ReplacementGroups { public static void main(String[] args) { String input = "Name: John Doe, Phone: (123) 456-7890"; String regex = "Name: (\\w+) (\\w+), Phone: \\((\\d{3})\\) (\\d{3})-(\\d{4})"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); if (matcher.find()) { System.out.println("Total groups: " + matcher.groupCount()); // Simple replacement using group references String result1 = matcher.replaceAll("Contact: $1 $2, Phone: ($3) $4-$5"); System.out.println("\nReplacement 1: " + result1); // More complex replacement using group count StringBuilder sb = new StringBuilder(); for (int i = 1; i <= matcher.groupCount(); i++) { sb.append("Group ").append(i).append(": [") .append(matcher.group(i)).append("] "); } String result2 = matcher.replaceAll(sb.toString()); System.out.println("Replacement 2: " + result2); } } }
此示例显示了使用组引用的两个替换操作。 groupCount
帮助我们了解可以在替换中引用多少个组。 第一个替换使用固定的组引用,而第二个替换基于组计数动态构建替换。
输出演示了替换字符串中的组引用($1、$2 等)如何对应于捕获的组。 了解组计数对于创建正确的替换模式至关重要。
来源
在本文中,我们通过各种示例彻底探讨了 MatchResult.groupCount
方法。 理解组计数对于 Java 中有效的正则表达式处理至关重要。
作者
列出所有Java教程。