我正试图从文字中获取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"
这是我想要的,但是每个记录都可以显示为零时间且此正则表达式不适合
我应该使用什么模式?
答案 0 :(得分:5)
你想让你的量词非贪婪,你想要使用锚点:
^.*?(Record1.*?)?(Record2.*?)?(Record3.*?)?$
在原始表达式中,.*
基本上消耗了字符串末尾的所有内容,因为这是正则表达式的行为方式,默认情况下(称为贪婪匹配)。由于第二组和第三组是可选的,因此引擎不没有理由简单地匹配所有第一组.*
- 这是最有效的匹配。
通过在任何量词之后添加?
,例如 *?
或+?
或??
或{m,n}?
,您可以指示引擎尽可能少地匹配 ,即调用非贪婪匹配。
那么,为什么锚?好吧,如果你调用非贪婪的匹配,引擎会尝试尽可能少地匹配 。所以,它匹配 nothing ,因为你的所有组都是可选的!通过强制整个表达式与开头^
以及结尾$
匹配,您可以强制使用正则表达式来找到通过.*?
匹配尽可能少的字符的方法,但仍然需要尽可能多地获得所有细节。
答案 1 :(得分:0)
如果您的文字紧凑且仅由Record
组成,为什么不使用拆分
(如果Java称之为拆分)。
拆分正则表达式:
# "(?:(?!Record)[\\S\\s])*(Record[\\S\\s]*?)(?=Record|$(?!\\n))"
(?:
(?! Record )
[\S\s]
)*
( Record [\S\s]*? )
(?=
Record
| $ (?! \n )
)