这个样式:
/a+?b+?/
对应以下字符串:
aaaaaabbbbbb
匹配:aaaaaab
我们看到非贪婪在向后/左方向(取全部)和向前/右方向(只取一个)上的行为是不同的。
是否有一种方法使一开始的非贪婪匹配所有a
,也尽可能少地匹配?所以它的行为和最后的b
部分是一样的?
简短回答
正则表达式通常从左到右匹配,除非您设置了从右到左的标志(很少有样式支持)。在任何一种情况下,它们都不会从中间开始,然后向两个方向发展,即使你使用向后看。
懒惰量词是如何工作的?
停下来问问——为什么懒惰量词首先存在?它要解决什么问题?
普通(贪婪)量词的工作原理是找到文本的匹配模式,然后重复匹配一系列字符,直到它们无法再匹配为止。这种行为通常是需要的,但是当您有一个非常通用的模式后跟一个非常特定的模式,并且特定模式是通用模式的子集时,您就会遇到问题。
例如,考虑以下输入:
_abc_END_def_END
这个模式:
(w+END)
的目的是匹配_abc_
,然后END
。问题是END
是w+
的子集。使用标准的"贪婪";规则,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
它们的行为是一样的!一个惰性量词(在本例中是一个惰性+
)告诉正则表达式引擎
- 从第一个可能的位置开始,
- 然后匹配尽可能少的字符(在
+
的情况下至少一个) - ,但匹配尽可能多,以允许整体匹配发生。
正则表达式不匹配"向左"或"向后",因为你似乎暗示。
你到底想达到什么目的?我猜它不是这个简单的例子-这将是微不足道的修复(只需使regexab
,这可能不是你正在寻找的)。