java - 正则表达式非贪婪交替
问题描述
我想检查文件的每一行是否与多个正则表达式模式匹配。
示例:测试我的文本文件的这一行
123;456;789
针对 3 种不同的表达方式
1.*;.*;..9
3.*;.*;787
.2.;.*;..9
并在模式匹配或不匹配时做一些事情。所以我需要知道在这个例子中我的所有模式中哪一个匹配或不匹配:只有 P1 和 P3 匹配,所以我在输入上执行动作 1 和动作 3123;456;789
带有嵌套 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);
}
}
但是引擎在第一个匹配的选项处停止
有没有办法在一次调用中测试多种不同的模式?否则我怎样才能改进算法而不是二次的
解决方案
这是正则表达式引擎在找到成功匹配时停止的正确行为。要模拟您正在尝试做的事情,您应该使用前瞻,但它们不会中断比赛(很快失败或很快成功)。因此,类似以下正则表达式的内容将尝试匹配三个不同的捕获组。如果捕获组中的一个正则表达式无法匹配,因为它是可选的,则尝试另一个前瞻,这一直持续到结束:
^(?=(1.*;.*;..9$)?)(?=(3.*;.*;787$)?)(?=(.2.;.*;..9$)?)
如果一个组被捕获,您只需要稍后使用捕获组来执行一些代码:
if (capturingGroup == 1) {
// do something
} else if (capturingGroup == 2) {
...
在此处查看现场演示(在这里您的两个正则表达式匹配且可识别)
注意:您可能希望删除点星以支持更严格的模式。目前它匹配这么多。
注意:由于这里的两个正则表达式不会同时匹配,您可以将上述正则表达式更改为:
^(?:(?=(1.*;.*;..9$)?)(?=(.2.;.*;..9$)?)|(3.*;.*;787)$)
推荐阅读
- javascript - ScrollTop 仅滚动到可滚动 div 中可见的第一个视图项目
- excel - 何在 excel VBA 中处理服务器/公司内部网络
- templates - 如何获取 Sphinx 模板中根文件夹的路径?
- javascript - SyntaxError:等待仅在异步函数中有效我如何使用异步?
- excel - 如果单元格名称已存在于 Excel 中的上一行中,则删除行
- wordpress - 如何在 wordpress 中编写截断查询?
- android - JetPack Compose:执行 KeyBoardAction
- ionic-framework - 带有 Agora-Rtc-SDK 的 Ionic 应用程序 - 流播放问题
- sql-server - 从 Apache Spark Databricks 读取到 Azure DB 时,与主机端口 1433 的 TCP/IP 连接失败
- docker - 当我在本地开发时,我的 docker 实例可以更新吗?