在没有线性搜索的情况下,找出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;
}