2014-11-06 51 views
1

代码:JAVA REGEX:如何找到完全匹配的组?

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匹配。

我的问题是没有任何迭代,有没有办法找到完全匹配的组?

回答

3

给定一个正则表达式(group1)|(group2)|(group3)|...|(groupn),这是不可能知道哪个组的文本,而无需通过至少(N - 1)去匹配组,检查其是否捕捉一些文字或者是null

但是,您可以通过调用Matcher.start(int group)来减少字符串构造的开销,并检查返回的索引是否为负数(大于或等于0)。


顺便说一句,这是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]; 
} 

理论上,有可能知道哪个组matc通过检查O(log n)捕获组来查看文本。您可以通过为组1添加捕获组(组2)和组(n div 2 + 1)到组n来创建搜索树。这允许您通过跟随匹配的分支来搜索与文本匹配的组。不过,我建议不要这样做,因为逻辑非常复杂且容易出错(添加了较大的捕获组后,组号会发生变化,而组数不一定总是2的幂)。

+0

+1和使用'Match.start'是一个很好的建议。 – 2014-11-06 09:42:51

0

不幸的是无法做到这一点。你可以,我想,破解它的简单的情况下,像你的例子,如:

if (mat.find()) { 
    int group = (mat.group(1) == null ? 2 : 1); 
} 

但这不会获得你多少,你永远要经过至少n-1(假定匹配被找到)n个组的比较(注意以上仍然是1组检查2组)。如果你不想依赖组的排序,你可以使用命名捕获组。虽然这并不能实现您的目标,但它确实为您提供了在regex中重新排序组的灵活性,而无需修改代码中的整数值以匹配。