在向后方向上使非贪婪RegEx的行为与向前方向相同



这个样式:

/a+?b+?/

对应以下字符串:

aaaaaabbbbbb
匹配:

aaaaaab

我们看到非贪婪在向后/左方向(取全部)和向前/右方向(只取一个)上的行为是不同的。

是否有一种方法使一开始的非贪婪匹配所有a,也尽可能少地匹配?所以它的行为和最后的b部分是一样的?

简短回答

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

懒惰量词是如何工作的?

停下来问问——为什么懒惰量词首先存在?它要解决什么问题?

普通(贪婪)量词的工作原理是找到文本的匹配模式,然后重复匹配一系列字符,直到它们无法再匹配为止。这种行为通常是需要的,但是当您有一个非常通用的模式后跟一个非常特定的模式,并且特定模式是通用模式的子集时,您就会遇到问题。

例如,考虑以下输入:

_abc_END_def_END

这个模式:

(w+END)

的目的是匹配_abc_,然后END。问题是ENDw+的子集。使用标准的"贪婪";规则,w+尽可能匹配。所以它不是匹配_abc_,而是匹配_abc_END_def

此场景的解决方案是使用惰性修饰符?改变量词(+)的行为方式。通过将表达式更改为w+?, regex引擎被迫只匹配满足表达式所需的部分,而不是更多。当w+?匹配_abc_, END匹配其字面值字符串时满足表达式。

惰性量词的目的不是匹配一个"最小值"。字符数——这是关于给第二种模式,第一种模式的子集,一个匹配的机会。

回到你的问题

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

ab

或者,如果您的a是某个可能包含b的超集的替代:

[ab]b
例如:

wb

两者都匹配:

ab

的例子:

const input = "aaabbb"
console.log(/ab/.exec(input)[0])

前面加上贪婪非捕获组:

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

如果您没有能力进行前面提到的从右到左匹配,那么您可以简单地反转字符串,反转正则表达式,然后在最后反转结果。

工作如下:

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

它们的行为是一样的!一个惰性量词(在本例中是一个惰性+)告诉正则表达式引擎

  • 从第一个可能的位置开始,
  • 然后匹配尽可能少的字符(在+的情况下至少一个)
  • ,但匹配尽可能多,以允许整体匹配发生。

正则表达式不匹配"向左"或"向后",因为你似乎暗示。

你到底想达到什么目的?我猜它不是这个简单的例子-这将是微不足道的修复(只需使regex ab,这可能不是你正在寻找的)。

最新更新