正則表達式的貪婪模式與非貪婪模式

作為開始,我們先看下面的正則:

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

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

之所以出現(xiàn)這個結局,是因為正則的貪婪模式在起作用。

一、貪婪模式(默認)

首先我們假設自己是正則引擎,來模擬搜索實現(xiàn)的過程。
正則引擎先從字符串的第0位開始搜索。

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

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

    一直尋找到最后
  3. 當文本結束后,點的匹配停止了,但仍然有剩余的正則"需要匹配,因此正則引擎開始倒過來回溯,換句話說,就是一個字符一個字符縮減匹配。

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

    當匹配縮減后,它開始嘗試匹配剩余的正則,但"沒有匹配上字符e。

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

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

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

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

二、非貪婪模式

非貪婪模式和貪婪模式相反,可通過在代表數(shù)量的標識符后放置?來開啟非貪婪模式,如?、+?甚至是??。

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

我們來看看非貪婪模式.?是怎么運轉的:

  1. 第一步和上面類似,引號"被匹配上

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

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

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

    可惜沒有匹配上,因為t!="

  4. .重復更多的字符,再進行嘗試

    往后尋找"

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

  5. 下面終于匹配上了

    找到"了, 后面可能還有,繼續(xù)找
  6. 因為正則是global的,所以正則引擎繼續(xù)后面的匹配,從引號后面的a字符開始,后面又匹配到第二個字符串

    就這樣找到更多的"

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

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

相關閱讀更多精彩內容

友情鏈接更多精彩內容