正則表達(dá)式的貪婪模式與非貪婪模式

作為開(kāi)始,我們先看下面的正則:

var str = 'a "witch" and her "broom" is one';
str.match( /".*"/g);

我們本來(lái)預(yù)想上面會(huì)匹配得到"witch""broom"兩個(gè)字符串,運(yùn)行上面的例子,卻發(fā)現(xiàn)結(jié)果只匹配到"witch" and her "broom"一個(gè)字符串。

之所以出現(xiàn)這個(gè)結(jié)局,是因?yàn)檎齽t的貪婪模式在起作用。

一、貪婪模式(默認(rèn))

首先我們假設(shè)自己是正則引擎,來(lái)模擬搜索實(shí)現(xiàn)的過(guò)程。
正則引擎先從字符串的第0位開(kāi)始搜索。

  1. 第一個(gè)查找字符是",正則引擎在第三個(gè)位置匹配到了它:
尋找字符串"
  1. 之后,引擎嘗試匹配正則的剩余部分,第二個(gè)字符是.,它代表任意字符。引擎匹配到了w:

    尋找任意字符.
  2. .代表任意字符重復(fù)一次到多次,因此正則引擎匹配到所有字符

    一直尋找到最后
  3. 當(dāng)文本結(jié)束后,點(diǎn)的匹配停止了,但仍然有剩余的正則"需要匹配,因此正則引擎開(kāi)始倒過(guò)來(lái)回溯,換句話說(shuō),就是一個(gè)字符一個(gè)字符縮減匹配。

    找到最后了,但最后的字符不是",又要從后往前找"

    當(dāng)匹配縮減后,它開(kāi)始嘗試匹配剩余的正則,但"沒(méi)有匹配上字符e。

  4. 因此正則繼續(xù)縮減.所重復(fù)的字符,繼續(xù)嘗試。

一直找"
  1. 正則引擎回溯,一次一次縮減.重復(fù)的字符個(gè)數(shù),直到剩余的正則都匹配上:

    從后往前終于找到"了
  2. 現(xiàn)在"終于匹配上了。 如果正則是global的,正則引擎會(huì)從上次匹配結(jié)果之后繼續(xù)查找更多結(jié)果。

總結(jié):在貪婪(默認(rèn))模式下,正則引擎盡可能多的重復(fù)匹配字符。

二、非貪婪模式

非貪婪模式和貪婪模式相反,可通過(guò)在代表數(shù)量的標(biāo)識(shí)符后放置?來(lái)開(kāi)啟非貪婪模式,如?+?甚至是??。

var str = 'a "witch" and her "broom" is one';
str.match(/".*?"/g )     // "witch", "broom"

我們來(lái)看看非貪婪模式.?是怎么運(yùn)轉(zhuǎn)的:

  1. 第一步和上面類似,引號(hào)"被匹配上

    尋找字符串"
  2. 第二步也一樣, '.'被匹配上

    尋找任意字符.
  3. 下面是二者的重要區(qū)別。 正則引擎嘗試用最小可能的重復(fù)次數(shù)來(lái)進(jìn)行匹配,因此在.匹配了w后,它立即嘗試"的匹配

    找到.后繼續(xù)找"

    可惜沒(méi)有匹配上,因?yàn)?code>t!="。

  4. .重復(fù)更多的字符,再進(jìn)行嘗試

    往后尋找"

    又沒(méi)匹配上,繼續(xù)~~

  5. 下面終于匹配上了

    找到"了, 后面可能還有,繼續(xù)找
  6. 因?yàn)檎齽t是global的,所以正則引擎繼續(xù)后面的匹配,從引號(hào)后面的a字符開(kāi)始,后面又匹配到第二個(gè)字符串

    就這樣找到更多的"

總結(jié):在非貪婪模式下,正則引擎盡可能少的重復(fù)匹配字符。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容