0

我不明白为什么.这个正则表达式中的 不贪婪地匹配整个字符串:

var re = /.+b/g,
    st = "aaaaaabcd";

console.log( st.match(re) ); //["aaaaaab"]

http://jsbin.com/UmOraTI/1/edit?js,输出

我一直在尝试了解贪婪,似乎.+应该匹配所有字符,因为.基本上匹配所有字符。与 相同*。有人可以解释一下吗?

4

4 回答 4

7

可以匹配整个.+字符串,但是后面的b没有可匹配的。贪婪匹配意味着它会尽可能多地匹配,同时仍然使后面的模式有可能成功匹配。

于 2013-09-13T18:38:34.293 回答
2

好吧,.+肯定贪婪……你只是看不到它!

正则表达式引擎将匹配d字符串中的所有字符,一旦出现,查找b,但无处可寻。

因此它返回一个字符(称为回溯),现在在一次c又一次d尝试匹配b,但没有成功(d在前面,不是b)。

它再次回溯以介于两者之间bc但再次失败。

它再次回溯并进入两者之间ab最终匹配!这就是它停止回溯并返回您看到的结果的地方。

这就是为什么你得到:

var re = /.+b/g,
    st = "aaaaaabcdbaa";

console.log( st.match(re) ); //["aaaaaabcdb"]

它在最后 2 秒后回溯并在最后a匹配。 b

这是贪婪!

反过来....

var re = /.+?b/g,
    st = "aaaaaabcdbaa";

console.log( st.match(re) ); //["aaaaaab"]

这是懒惰。

一些引擎有操作符来防止这种回溯,这个过程通常会使正则表达式变得非常慢;想象一下必须在一个字符串中多次回溯(.*通常有很多)。

于 2013-09-13T18:43:36.473 回答
0
var re = /<tr>.*<\/tr>/g,
    st = "<tr>asdf</tr>blah<tr>asdf</tr>";

console.log( st.match(re) );

你必须小心正则表达式中的贪婪数学。上面的例子仍然匹配整个字符串。取自您的 jsbin。

于 2013-09-13T18:44:18.727 回答
0

实际上,在某种程度上,它确实匹配整个字符串。您的正则表达式匹配器执行称为backtracking的操作,这会导致它备份,直到找到合适的匹配项。所以用你的表情:

/.+b/

比赛是这样的:

    aaaaaabcd
.+  ---------
b            x

然后它发现它无法匹配 be,因此.+术语“放弃”它的一个匹配项,mather 再次尝试:

    aaaaaabcd
.+  --------
b           x

仍然没有匹配,所以它放弃了另一个,(这无济于事)和另一个,直到它达到这个状态:

    aaaaaabcd
.+  ------
b         -

哪个是正则表达式的最长匹配项。

于 2013-09-13T18:43:15.907 回答