如何regExp'零或一个'组包含'。*'

时间:2013-11-17 18:59:12

标签: 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"

这是我想要的,但是每个记录都可以显示为零时间且此正则表达式不适合

我应该使用什么模式?

2 个答案:

答案 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 )
 )