既然“a +?”懒惰,为什么“a +?b”匹配“aaab”?

时间:2014-07-23 00:33:12

标签: javascript regex

在使用 JavaScript:The Definitive Guide 在javascript中学习正则表达式时,我对此段感到困惑:

  

但/ a +?/匹配字母a的一个或多个匹配项,匹配为   必要的几个字符。当应用于相同的字符串时,这个   pattern只匹配第一个字母a。

     

...

     

现在让我们使用nongreedy版本:/ a +?b /。这应该匹配   字母b前面有最少数量的可能。申请时   对于相同的字符串“aaab”,您可能希望它只匹配一个和a   最后一个字母b。但事实上,这种模式与整个模式相匹配   字符串,就像模式的贪婪版本一样。

为什么会这样?

这是书中的解释:

  

这是因为通过查找来完成正则表达式模式匹配   字符串中可以匹配的第一个位置。既然一个   可以从第一个字符开始匹配   字符串,从后续字符开始的短匹配永远不会   甚至考虑过。

我不明白。谁能给我一个更详细的解释呢?

4 个答案:

答案 0 :(得分:5)

好的,你有搜索空间," aaabc"和你的模式,/ a +?b /

/ a +?b /匹配" a"?否。

是/ a +?b /匹配" aa"?否。

是/ a +?b /匹配" aaa"?否。

/ a +?b /匹配" aaab"?是。

答案 1 :(得分:5)

由于您匹配文字字符而不是任何类型的通配符,因此正则表达式a+?b实际上与a+b完全相同。一个匹配的唯一序列类型是一个或多个a个字符后跟单个b字符的字符串。非贪婪修饰符在这里没有区别,因为a可能匹配的唯一内容是a

非贪婪的限定符在应用于可以采用许多不同值的内容时会变得很有趣,例如.。 (编辑a+?之类左侧有趣的内容

编辑 - 如果您希望a+?b仅匹配ab之前的aaab,那么& #39;不是它的工作原理。隐式地在字符串中搜索模式意味着搜索模式的最早出现。因此,虽然从上一个a开始确实给出了与模式匹配的子字符串,但它不是匹配的第一个子字符串。

答案 2 :(得分:3)

''在+之后表示满足表达式的最小字符数。 / a + /表示一个' a'或者在遇到其他角色之前你可以遇到多少。为了满足/ a +?/(因为它的nogreedy)它只需要单个' a。

为了满足/ a +?b /,因为我们有' b'最后,为了满足这个表达式,它需要匹配一个或多个' a'在它出现之前' b'它必须击中那个' b'。 / a + /不必打b,因为RegEx没有要求。 / a +?b /必须达到' b'。

想一想。还有什么其他含义/ a +?b /可以有什么?

希望这有帮助

答案 3 :(得分:3)

引擎在字符串的开头尝试匹配

  

有人能给我更详细的解释吗?

是。

简而言之:.+?不会在整个字符串的整体上查找全局最短匹配,而是在本地,从引擎当前所在的字符串中的位置查找。

引擎的工作原理

当您对字符串aaab尝试正则表达式时,引擎首先尝试从字符串中的第一个位置开始查找匹配项。该位置是第一个a之前的位置。如果引擎在第一个位置找不到匹配项,它会继续前进并从第二个位置开始重试(在第一个和第二个a之间)

那么第一个位置的正则表达式a+?b可以找到匹配吗?是。

  • a与第一个a
  • 相匹配
  • +?量词告诉引擎匹配最少数量的a字符。由于我们希望返回匹配项,必需表示必须允许以下令牌(在本例中)匹配。在这种情况下,允许a匹配所需的b个字符数最少的是所有剩余的a个字符。
  • b匹配

在细节中,第二点有点复杂(引擎尝试将b与第二个a匹配,失败,回溯......)但您无需担心这一点。