在没有线性搜索的情况下,找出Java正则表达式中匹配的组?

在没有线性搜索的情况下,找出Java正则表达式中匹配的组?,java,regex,regex-group,Java,Regex,Regex Group,我有一些通过编程组装的大型正则表达式,如下所示 (A)|(B)|(C)|... 每个子模式都在其捕获组中。当我得到一个匹配项时,我如何在不线性测试每个组(I)的情况下找出哪个组匹配以查看它是否返回非空字符串?如果您的正则表达式是通过编程生成的,为什么不通过编程生成n个单独的正则表达式并依次测试它们呢?除非它们共享一个共同的前缀,而且Java正则表达式引擎很聪明,否则所有的替代方案都会得到测试 更新:我刚刚浏览了Sun Java源代码,特别是Java.util.regex.Pattern$Bra

我有一些通过编程组装的大型正则表达式,如下所示

(A)|(B)|(C)|...

每个子模式都在其捕获组中。当我得到一个匹配项时,我如何在不线性测试每个
组(I)
的情况下找出哪个组匹配以查看它是否返回非空字符串?

如果您的正则表达式是通过编程生成的,为什么不通过编程生成n个单独的正则表达式并依次测试它们呢?除非它们共享一个共同的前缀,而且Java正则表达式引擎很聪明,否则所有的替代方案都会得到测试


更新:我刚刚浏览了Sun Java源代码,特别是Java.util.regex.Pattern$Branch.match(),这也只是对所有备选方案进行线性搜索,依次尝试。使用Branch的其他地方不建议对常用前缀进行任何类型的优化。

将正则表达式分成三部分:

String[] regexes = new String[] { "pattern1", "pattern2", "pattern3" };

for(int i = 0; i < regexes.length; i++) {
  Pattern pattern = Pattern.compile(regexes[i]);

  Matcher matcher = pattern.matcher(inputStr);
  if(matcher.matches()) {
     //process, optionally break out of loop
  }
}

public int getMatchedGroupIndex(Matcher matcher) { 
  int index = -1;  

  for(int i = 0; i < matcher.groupCount(); i++) {
    if(matcher.group(i) != null && matcher.group(i).trim().length() > 0) {
      index = i;
    }
  }

  return index;
}
String[]regexes=新字符串[]{“pattern1”、“pattern2”、“pattern3”};
for(int i=0;i0){
指数=i;
}
}
收益指数;
}
另一种选择是:

for(int i = 0; i < matcher.groupCount(); i++) {
  if(matcher.group(i) != null && matcher.group(i).trim().length() > 0) {
     //process, optionally break out of loop
  }
}
for(int i=0;i0){
//进程,可选地断开循环
}
}

我认为你无法绕过线性搜索,但是你可以通过使用
start(int)
而不是
group(int)
来提高效率

static int getMatchedGroupIndex(匹配器m)
{ 
int指数=-1;

对于(int i=1,n=m.groupCount();i,从各种注释来看,简单的答案似乎是“否”,而使用单独的正则表达式是一个更好的主意。为了改进这种方法,您可能需要在生成常见的模式前缀时找出它们,或者使用您自己的正则表达式(或其他)模式匹配引擎。但在进行所有这些工作之前,您需要确保这是系统中的一个重要瓶颈。换句话说,对其进行基准测试,看看实际输入数据的性能是否可以接受,如果不是配置文件,则查看真正的瓶颈在哪里。

相反,您可以使用非捕获组广告:

(A) |(B)|(C)|

取代

((?:A)|(?:B)|(?:C))


非捕获组(?:)将不包括在组计数中,但分支的结果将捕获在外部()组。

你想找到哪个组匹配或组的内容吗?我不知道有一个正则表达式系统可以满足你的要求,我很确定core Java中的一个系统可以线性地实现它。有关更多详细信息,请参阅@Thomas的帖子。是的,他们可能共享前缀等。我不想进行线性搜索。我想问的是,我是否可以得到这个不存在的方法Matcher.getMatchedGroupIndex()的功能,它会神奇地告诉我哪个组是匹配的,而无需我遍历每个组来测试它。我添加了getMatchedGroupIndex()方法,但在封面下它仍将使用FOR循环来迭代组内容。
static int getMatchedGroupIndex(Matcher m)
{ 
  int index = -1;
  for (int i = 1, n = m.groupCount(); i <= n; i++)
  {
    if ( (index = m.start(i)) != -1 )
    {
      break;
    }
  }
  return index;
}