无限的时间使懒惰搜索停止

时间:2019-08-04 09:41:39

标签: regex

我有这句话:

<i>foo 42 </i> <i>(bar)</i>

如果我尝试将其与此正则表达式匹配:

<i>(foo \d+\s*.+?)(\(bar\))

结果的第1组是:

foo 42 </i> <i>

但是,如果我将?放在正则表达式的末尾是因为(bar)可能存在或可能不存在:

<i>(foo \d+\s*.+?)(\(bar\))?

结果的组1变为:

foo 42 <

如何为foo 42 </i> <i>组使用?量词来获得(bar)

谢谢

1 个答案:

答案 0 :(得分:1)

要点是,如果这种匹配发生在一个或零个字符之后,那么在一个惰性点模式之后的所有可选子模式都将与其模式匹配。

也就是说,如果<i>(foo \d+\s*.+?)(\(bar\))?遵循0个或多个空格和1个字符,例如(bar)<i>foo 42 <(bar)</i>(请参阅demo),它将抢占<i>foo 42<(bar)</i>

由于您要匹配任意可选的(bar),因此需要确保将.+?转换为tempered greedy token并可以与贪婪的量词一起使用,但是脾气暴躁,前瞻性有限:

<i>(foo \d+\s*(?:(?!\(bar\)).)*)(\(bar\))?

或者,如果您需要将最近 foo <digits>(bar)相匹配:

<i>(foo \d+\s*(?:(?!\(bar\)|foo \d).)*)(\(bar\))?

请参见Regex 1Regex 2演示。

详细信息

  • <i>-文字字符串
  • (foo \d+\s*(?:(?!\(bar\)|foo \d).)*)-第1组:
    • foo \d+-foo,空格和1个以上的数字
    • \s*-超过0个空格
    • (?:(?!\(bar\)|foo \d).)*-尽可能不出现0个或更多字符的任何字符,但不以(bar)foo,空格,数字字符序列开头
  • (\(bar\))?-可选的第2组:(bar)子字符串。