我正在尝试从文本中获取 record1
、record2
、record3
:
"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/