java - 如何对包含 'zero or one' 的 '.*' 组进行正则表达式

标签 java regex

我正在尝试从文本中获取 record1record2record3:

"Record1 ANY TEXT 123 4 5 Record2 ANOTHER TEXT 90-8098 Record3 MORE TEXT ASD 123"

每条记录出现一次或零次。 我使用模式:

(Record1.*)?(Record2.*)?(Record3.*)?

如果出现每条记录,

matcher.group(1) == "Record1 ANY TEXT 123 4 5 Record2 ANOTHER TEXT 90-8098 Record3 MORE TEXT ASD 123"
matcher.group(2) == null
matcher.group(3) == null

如果我使用模式:

(Record1.*)(Record2.*)(Record3.*)

matcher.group(1) == "Record1 ANY TEXT 123 4 5 "
matcher.group(2) == "Record2 ANOTHER TEXT 90-8098 "
matcher.group(3) == "Record3 MORE TEXT ASD 123"

这正是我想要的,但是每条记录都可以出现零次,这个正则表达式不合适

我应该使用什么模式?

最佳答案

你想让你的量词非贪婪,并且你想使用 anchor :

^.*?(Record1.*?)?(Record2.*?)?(Record3.*?)?$

在您的原始表达式中,您的 .* 基本上消耗了字符串末尾的所有内容,因为默认情况下这就是正则表达式的行为方式(称为贪婪匹配) .由于第二组和第三组是可选的,因此引擎没有理由简单地将所有内容与第一个匹配。*——这是最有效的匹配。

通过在任何量词之后添加 ?例如 *?+?? ?{m,n}?,您指示引擎匹配尽可能少调用非贪婪匹配

那么,为什么要 anchor ?好吧,如果您调用非贪婪匹配,引擎将尝试匹配尽可能少。所以,它会匹配nothing,因为你所有的组都是可选的!通过强制整个表达式匹配开头 ^ 以及结尾 $,您强制正则表达式找到某种方式来匹配尽可能少的字符通过 .*?,但仍会根据需要进行匹配以获取所有详细信息。

关于java - 如何对包含 'zero or one' 的 '.*' 组进行正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20034818/

相关文章:

java - 用于检查电子邮件 ID 的正则表达式

java - 如何避免 NetBeans Java 项目中 GWT Horizo​​ntalSplitPanel 的弃用警告?

java - URL连接和内容长度: how much data is download?

php - 非贪婪通配符 "ignored"

regex - 在 greylog 搜索中尝试正则表达式模式

Ruby - 数组中至少有一项也符合要求

java - 正则表达式匹配一定长度的单词

Java 静态变量的序列化问题

java - 在java中使用stream api的复杂操作

java - 无法初始化 Mockito