我不明白为什么.
这个正则表达式中的 不贪婪地匹配整个字符串:
var re = /.+b/g,
st = "aaaaaabcd";
console.log( st.match(re) ); //["aaaaaab"]
http://jsbin.com/UmOraTI/1/edit?js,输出
我一直在尝试了解贪婪,似乎.+
应该匹配所有字符,因为.
基本上匹配所有字符。与 相同*
。有人可以解释一下吗?
我不明白为什么.
这个正则表达式中的 不贪婪地匹配整个字符串:
var re = /.+b/g,
st = "aaaaaabcd";
console.log( st.match(re) ); //["aaaaaab"]
http://jsbin.com/UmOraTI/1/edit?js,输出
我一直在尝试了解贪婪,似乎.+
应该匹配所有字符,因为.
基本上匹配所有字符。与 相同*
。有人可以解释一下吗?
可以匹配整个.+
字符串,但是后面的b
没有可匹配的。贪婪匹配意味着它会尽可能多地匹配,同时仍然使后面的模式有可能成功匹配。
好吧,.+
肯定是贪婪……你只是看不到它!
正则表达式引擎将匹配d
字符串中的所有字符,一旦出现,查找b
,但无处可寻。
因此它返回一个字符(称为回溯),现在在一次c
又一次d
尝试匹配b
,但没有成功(d
在前面,不是b
)。
它再次回溯以介于两者之间b
,c
但再次失败。
它再次回溯并进入两者之间a
并b
最终匹配!这就是它停止回溯并返回您看到的结果的地方。
这就是为什么你得到:
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"]
这是懒惰。
一些引擎有操作符来防止这种回溯,这个过程通常会使正则表达式变得非常慢;想象一下必须在一个字符串中多次回溯(.*
通常有很多)。
var re = /<tr>.*<\/tr>/g,
st = "<tr>asdf</tr>blah<tr>asdf</tr>";
console.log( st.match(re) );
你必须小心正则表达式中的贪婪数学。上面的例子仍然匹配整个字符串。取自您的 jsbin。
实际上,在某种程度上,它确实匹配整个字符串。您的正则表达式匹配器执行称为backtracking的操作,这会导致它备份,直到找到合适的匹配项。所以用你的表情:
/.+b/
比赛是这样的:
aaaaaabcd
.+ ---------
b x
然后它发现它无法匹配 be,因此.+
术语“放弃”它的一个匹配项,mather 再次尝试:
aaaaaabcd
.+ --------
b x
仍然没有匹配,所以它放弃了另一个,(这无济于事)和另一个,直到它达到这个状态:
aaaaaabcd
.+ ------
b -
哪个是正则表达式的最长匹配项。