向后方向做一个非贪婪的RegEx,就像向前方向一样

时间:2013-03-03 21:47:14

标签: regex pcre regex-greedy non-greedy

这种模式:

/a+?b+?/

反对以下字符串:

aaaaaabbbbbb

匹配

aaaaaab

我们看到非贪婪在向后/向左方向(全部采用)和向前/向右方向(只采用一条)方面表现不同。

有没有办法让开头的非贪婪与所有a匹配,以尽可能少地匹配?那么它的行为方式与最后的b部分相同?

4 个答案:

答案 0 :(得分:4)

正则表达式通常从左到右匹配,除非您设置从右到左的标志(支持非常少的风格)。在任何一种情况下,它们都不会从中间开始,然后在两个方向上锻炼,即使你使用了后视镜。

它有助于停止并询问 - 为什么懒惰量词首先存在?它有什么问题需要解决?

正常(贪婪)量词通过找到匹配的文本模式然后重复匹配一系列字符直到它们不再匹配来工作。通常需要这种行为,但是如果您有一个非常通用的模式,然后是一个特定模式,其中特定模式是一般模式的子集,则会遇到问题。

例如,请考虑以下输入:

_abc_END_def_END

这种模式:

(\w+END)(\w+END)?

很容易假设的意图是匹配_abc_然后END,然后是_def_,然后是END。此表达式似乎允许输入第二组字符是可选的。

问题是END\w+的子集,因此第二组实际上被\w+“消耗”,导致_abc_END_def_匹配,其次是END。这不是理想的行为。

此场景的解决方案是使用延迟修饰符更改量词的行为方式。这为END模式提供了与每个字符匹配的机会,并且只有在\w+失败时才允许END使用另一个字符。

延迟量词的目的是不匹配“最小”字符数 - 它是关于给第二个模式(第一个模式的子集)提供匹配的机会。

在您的示例中,b不是a的子集,因此不需要延迟量词。如果你想匹配一个或多个a,但尽可能少,一个或多个b,但尽可能少,那么你只需使用:

ab

或者,如果您的a是某些超集的替身,可能包括b:

[ab]b

例如:

\wb

两者都匹配:

ab

答案 1 :(得分:1)

他们行为相同!惰性量词(在这种情况下是一个惰性+)告诉正则表达式引擎

  • 从第一个可能的位置开始,
  • 然后匹配尽可能少的字符(至少有一个+
  • 但可以根据需要进行匹配,以便进行整体匹配。

正如你所暗示的那样,正则表达式与“向左”或“向后”不匹配。

你到底想要达到什么目的?我想这不是一个简单的例子 - 修复是很容易的(只需要制作正则表达式ab,这可能不是你想要的那样。)

答案 2 :(得分:1)

如果您不必执行前面提到的右到左匹配,那么您可以简单地反转字符串,反转正则表达式,然后在结尾处反转结果。

工作如下:

Start with aaaaaabbbbbb
Reverse to bbbbbbaaaaaa
Reverse /a+?b+?/ to /b+?a+?/
The resulting Match is bbbbbba
Reverse the resulting match to get abbbbbb

答案 3 :(得分:0)

先加入贪婪的非捕获组:

/(?:a)*a+?b+?/