我想检查文件的每一行是否与多个regex模式匹配。
示例:测试我的文本文件的这一行
123;456;789针对3种不同的表达方式
1.*;.*;..9
3.*;.*;787
.2.;.*;..9并在模式匹配或不匹配时做一些事情。因此,在本例中,我需要知道我的所有模式中哪一个匹配或不匹配:只有P1和P3匹配,因此我在输入123;456;789上执行操作1和操作3。
嵌套for循环的朴素解决方案性能较差(因为该算法)。
示例:
for(String row : rows){
for (Pattern p : patterns){
if(p.matcher(value).matches()){
//
}
}
}我在考虑用一个“\”操作符内联多个正则表达式
使用上面的示例:(1.*;.*;..9)|(3.*;.*;787)|(.2.;.*;..9)
String expression = "(1.*;.*;..9)|(3.*;.*;787)|(.2.;.*;..9)";
String value = "123;456;789";
Pattern pattern = Pattern.compile(expression);
Matcher matcher = pattern.matcher(value);
HashMap<Integer,Boolean> results= new HashMap<>();
if(matcher.matches()) {
int count = matcher.groupCount();
for (int i = 1; i <= count; ++i) {
results.put(i, matcher.group(i) != null);
}
}但是引擎在第一个匹配选项停止。
是否有方法在一个调用中测试多个不同的模式?否则,我如何改进算法而不是二次型算法?
发布于 2019-04-03 10:44:49
这是regex引擎的正确行为,可以在找到成功匹配的位置停止。为了模拟你想要做的事情,你应该和看台一起工作,但是在某种程度上他们不会打断比赛(快失败或成功)。因此,下面的regex将尝试匹配三个不同的捕获组。如果捕获组中的一个正则表达式无法匹配,因为它是可选的,则尝试另一个向前看,直到结束:
^(?=(1.*;.*;..9$)?)(?=(3.*;.*;787$)?)(?=(.2.;.*;..9$)?)如果捕获了某个组,则只需要稍后与捕获组一起执行某些代码:
if (capturingGroup == 1) {
// do something
} else if (capturingGroup == 2) {
...参见现场演示 (在这里,您的两个正则表达式是匹配的和可识别的)
备注:您可能希望删除点星,以支持更严格的模式。目前它匹配的太多了。
注意事项:由于这里的两个正则表达式不能同时匹配,所以您可以将上面的正则表达式更改为:
^(?:(?=(1.*;.*;..9$)?)(?=(.2.;.*;..9$)?)|(3.*;.*;787)$)https://stackoverflow.com/questions/55492930
复制相似问题