# 捕获组

在上 一节中,我们看到了量化器一次附加到一个字符,字符类或捕获组。但直到现在,我们还没有详细讨论捕获组的概念。

捕获组 是将多个字符视为单个单元的方式。它们是通过将要分组在一组括号内的字符来创建的。 例如,正则表达式 (dog) 创建包含字母单个组"d" "o" 和 "g"。与捕获组匹配的输入字符串的部分将保存在存储器中, 以便以后通过反向引用进行调用(如下文“反向引用”部分所述)。

# 编号

如 Pattern API 中所述,捕获组通过从左到右计算其开始括号进行编号。在表达式中 ((A)(B(C))),有四个这样的组:

  1. ((A)(B(C)))
  2. (A)
  3. (B(C))
  4. (C)

要找出表达式中有多少组,请调用匹配器对象上的 groupCount 方法,该 groupCount 方法返回 int, 显示匹配器模式中存在的捕获组的数量。在此示例中,groupCount 将返回该数字 4,显示该模式包含 4 个捕获组。

还有一个特殊的组,组 0,它总是表示整个表达式。该组不包括在总报告中的 groupCount。开始的组(?是纯粹的非捕获组,不捕获文本,不计入组总数。(稍后在 Pattern 类的方法部分中将会看到非捕获组的示例 。)

了解组的编号很重要,因为某些 Matcher 方法接受 int 指定特定的组号作为参数:

  • public int start(int group): 返回上次匹配操作期间给定组捕获的子序列的起始索引。
  • public int end (int group): 返回上次匹配操作期间给定组捕获的最后一个字符的索引,加上一个子序列。
  • public String group (int group): 返回在上一个匹配操作期间由给定组捕获的输入子序列。

# 反向引用

与捕获组匹配的输入字符串的部分保存在存储器中,以便以后通过反向引用进行调用。反向引用在正则表达式中指定为反斜杠(\), 后跟数字,表示要调用的组的编号。例如,表达式 (\d\d) 定义了一行匹配一行中的两位数的捕获组,后者可以通过反向引用在表达式中调用该捕获组 \1

要匹配任何2位数,后跟完全相同的两位数,您将使用 (\d\d)\1 正则表达式:

---- Test code ----
regexTest("(\\d\\d)\\1", "1212");

---- Output ----
我发现文本中的 "1212" 在开始索引 0 和 结束索引 4.

1
2
3
4
5
6

如果您更改最后两位数字,则匹配将失败

---- Test code ----
regexTest("(\\d\\d)\\1", "1223");

---- Output ----
No match found.        
1
2
3
4
5

对于嵌套捕获组,反向引用的工作方式完全相同:指定反斜杠后跟要调用的组的编号。