13

这种模式:

/a+?b+?/

针对以下字符串:

aaaaaabbbbbb

火柴:

aaaaaab

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

有没有办法让一开始的非贪婪匹配所有的a, 也尽可能少地匹配?所以它的行为方式与b结尾部分的 at 相同?

4

4 回答 4

8

简短的回答

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

惰性量词如何工作?

它有助于停下来问 - 为什么惰性量词首先存在?它打算解决什么问题?

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

例如,考虑以下输入:

_abc_END_def_END

而这种模式:

(\w+END)

目的是匹配_abc_然后END. 问题是它END是 的一个子集\w+。使用标准的“贪婪”规则,\w+尽可能多地匹配。所以不是匹配_abc_,而是匹配_abc_END_def

+这种情况的解决方案是使用惰性修饰符更改量词 () 的行为方式?。通过将表达式更改为\w+?,正则表达式引擎被迫仅匹配满足表达式所需的匹配量,仅此而已。当\w+?匹配_abc_END匹配其文字字符串时,表达式得到满足。

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

回到你的问题

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

ab

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

[ab]b

例如:

\wb

两者都将匹配:

ab

例子:

const input = "aaabbb"

console.log(/ab/.exec(input)[0])

于 2013-03-04T14:12:51.997 回答
2

前面有贪婪的非捕获组:

/(?:a)*a+?b+?/
于 2019-02-27T17:21:37.687 回答
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
于 2016-03-10T20:55:15.657 回答
-1

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

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

正如您似乎暗示的那样,正则表达式不匹配“向左”或“向后”。

你到底想达到什么目的?我想这不是这个简单的例子 - 修复起来很简单(只需制作 regex ab,这可能不是你想要的)。

于 2013-03-03T21:53:28.333 回答