使用正则表达式中的可选块进行组编号

时间:2010-02-10 12:02:21

标签: java regex

有没有办法让括号中的表达式而不是被捕获到一个组中?

E.g。我的表达方式如下:

(A(B|C)?) D (E(F|G)?)

注意需要括号的(B|C)?(F|G)?的可选块 我对这些小组中的内容并不感兴趣。我想要的只是抓住完整的第一个和最后一个块。

但是由于可选块,组编号将会改变,我无法判断(E(F|G)?)是否被捕获为组2或3.

我可以告诉表达式忽略结果组中的可选部分,因此组编号将保持不变吗?或者我可以使可选的捕获总是出现在组中 - 即使它们是空的吗?

2 个答案:

答案 0 :(得分:15)

(E(F|G)?)将始终作为第3组捕获。编号由模式字符串中左括号的顺序决定,即:

(A(B|C)?) D (E(F|G)?)
^ ^         ^ ^
1 2         3 4

如果输入字符串中没有出现(B|C),则group(2)将返回null,但后续组将不会重新编号。

唯一不影响编号的组是非捕获组,例如

(A(?:B|C)?) D (E(?:F|G)?)
^             ^
1             2

示例:

Pattern pattern = Pattern.compile("(A(B|C)?) D (E(F|G)?)");
Matcher matcher = pattern.matcher("A D EG");
if (matcher.matches()) {
    System.err.println(matcher.group(1));
    System.err.println(matcher.group(2));
    System.err.println(matcher.group(3));
    System.err.println(matcher.group(4));
}

输出:

A
null
EG
G

答案 1 :(得分:9)

有非捕获组(?:…)

(A(?:B|C)?) D (E(?:F|G)?)

无法引用此类组的匹配。