js中正則表示式的貪婪模式和非貪婪模式
在講貪婪模式和惰性模式之前,先回顧一下JS正則基礎:
寫法基礎:
①不需要雙引號,直接用//包含 => /wehfwue123123/.test();
②反斜槓\表示轉義 =>/\.jpg$/
③用法基礎:.test(str);
語法:
①錨點類
/^a/=>以"a"開頭
/\.jpg$/=>以".jpg"結尾
②字元類
[abc]:a或b或c
[0-9]:一個數字
[a-z]:一個字母
. :任意字元
③元字元
^:在[]裡面用表示非,在[]外面用表示開頭
\d:[0-9]
\s:空白符
\w:[A-Za-z0-9_]
\D:[^\d]-非數字
\S:非空白符
④量詞
{m,n}:m到n次
元字元表示:
*:{0,}
?:{0,1}
+:{1,}
難點:貪婪模式/惰性模式
貪婪模式——在匹配成功的前提下,儘可能多的去匹配
惰性模式——在匹配成功的前提下,儘可能少的去匹配
解釋一:碼文並茂
使用正則表示式中的貪婪、惰性的量詞可以控制表示式匹配過程,我們知道量詞?、*、+的意義,可以指定相關模式出現的次數,預設的情況下我們使用的是貪婪量詞,它的匹配過程是從整個字串開始檢視,如果不匹配就去掉最後一個,再看看是否匹配,如此迴圈一直到匹配或字串空為止,如:
vars ="abbbaabbbaaabbb1234";
varre1=/.*bbb/g;//*是貪婪量詞
re1.test(s);
這個匹配過程將從整個字串開始:
re1.test("abbbaabbbaaabbb1234");//false ,則去掉最後一個字元4再繼續
re1.test("abbbaabbbaaabbb123");//false ,則去掉最後一個字元3再繼續
re1.test("abbbaabbbaaabbb12");//false ,則去掉最後一個字元2再繼續
re1.test("abbbaabbbaaabbb1");//false ,則去掉最後一個字元1再繼續
re1.test("abbbaabbbaaabbb");//true ,結束
在貪婪量詞的後面加多一個?就變成了惰性量詞,它的匹配過程相反,是從前面第一個開始,不匹配則加一個,如此迴圈直到字串結束,以上面的為例子。
vars ="abbbaabbbaaabbb1234";
varre1=/.*?bbb/g;//*?是惰性量詞
注意:?是加在bbb前面的,即緊跟對應的量詞後面
re1.test(s);
它的匹配過程如下:
re1.test("a");//false, 再加一個
re1.test("ab");//false, 再加一個
re1.test("abb");//false, 再加一個
re1.test("abbb");//true, 匹配了,儲存這個結果,再從下一個開始
re1.test("a");//false, 再加一個
re1.test("aa");//false, 再加一個
re1.test("aab");//false, 再加一個
re1.test("aabb");//false, 再加一個
re1.test("aabbb");//true, 匹配了,儲存這個結果,再從下一個開始
......
三.解釋二:直戳原理
貪婪與惰性模式區別如下:
一、從語法角度看
貪婪模式用於匹配優先量詞修飾的子表示式,匹配優先量詞包括:“{m,n}”、“{m,}”、“?”、“*”和“+”。
惰性模式用於匹配忽略優先量詞修飾子表示式,匹配忽略優先量詞包括:“{m,n}?”、“{m,}?”、“??”、“*?”和“+?”。
二、從應用角度看
兩者均影響被量詞修飾的子表示式匹配行為,貪婪模式在匹配成功的前提下儘可能多地匹配,而惰性模式則在匹配成功的前提下儘可能少匹配。惰性模式只被部分NFA引擎支援。
三、從匹配原理看
能達到同樣匹配結果的情況下,通常貪婪模式效率較高。
惰性模式都可通過修改量詞修飾的子表示式轉換為貪婪模式。
貪婪模式可以與固化分組結合,提升匹配效率,而惰性模式不行。
文/瑋哥今晚打老虎(簡書作者)
原文連結:http://www.jianshu.com/p/889f3885a5bd