代码:
String in = "text2";
Pattern pat = Pattern.compile("((?:text1))|((?:text2))");
Matcher mat = pat.matcher(in);
if(mat.find())
{
//print the matching group number
//without any iteration
//here the answer is group 2.
}
我的模式为((?:text1))|((?:text2))
,在“text2”与我的模式匹配时,它将mat.group(1)
设为空标题,将mat.group(2)
设为text2
。
所以我的输入与模式中匹配的组号2相匹配。
我的问题是没有任何迭代,有没有办法找到完全匹配的组?
答案 0 :(得分:3)
给定正则表达式(group1)|(group2)|(group3)|...|(groupn)
,无法通过至少(n - 1)个组来判断哪个组与文本匹配,并检查它是否捕获了某些文本或null
。< / p>
但是,您可以通过调用Matcher.start(int group)
来减少字符串构造的开销,并检查返回的索引是否为非负数(大于或等于0)。
顺便说一下,这是Oracle实施中Matcher.group(int group)
的源代码(版本8-b123):
public String group(int group) {
if (first < 0)
throw new IllegalStateException("No match found");
if (group < 0 || group > groupCount())
throw new IndexOutOfBoundsException("No group " + group);
if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
return null;
return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
}
与Matcher.start(int group)
相比,还有Oracle的实施版本8-b123:
public int start(int group) {
if (first < 0)
throw new IllegalStateException("No match available");
if (group < 0 || group > groupCount())
throw new IndexOutOfBoundsException("No group " + group);
return groups[group * 2];
}
理论上,可以通过检查O(log n)捕获组来判断哪个组与文本匹配。您可以通过将组1的捕获组添加到组(n div 2)和组(n div 2 + 1)组n来创建搜索树。这允许您通过跟随具有匹配项的分支来搜索与文本匹配的组。但是,我建议不要这样做,因为逻辑非常复杂且容易出错(在添加更大的捕获组之后组号会发生变化,并且组的数量并不总是2的幂)。
答案 1 :(得分:0)
不幸的是,这是不可能的。我想,你可以用像你的例子这样的简单案例来破解它,例如:
if (mat.find()) {
int group = (mat.group(1) == null ? 2 : 1);
}
但是这并没有给你带来太大的好处,而且你总是要经历至少n-1(假设找到匹配)对n组的比较(注意上面仍然是1组检查为2组)。
如果您不想依赖群组的排序,则可以使用命名捕获组。虽然这并没有实现您的目标,但它确实为您提供了在正则表达式中对组进行重新排序的灵活性,而无需修改代码中的整数值来匹配。