regex 忽略優先量詞

2021-08-28 11:15:56 字數 1889 閱讀 9408

正則裡的忽略優先量詞有*?+???,也就是匹配優先量詞加上乙個?,忽略優先也叫做我們平時說的惰性匹配

忽略優先量詞也是dfanfa的分水嶺,這個東西是nfa裡特有的,dfa裡沒有的。

忽略優先量詞與匹配優先量詞不同的地方在於,匹配優先量詞會首先嘗試匹配,而忽略優先量詞會先嘗試忽略,在儲存狀態的時候也是不一樣的,匹配優先量詞因為會先嘗試匹配,所以它的備用狀態儲存在該量詞的後面,而忽略優先量詞, 因為它會先嘗試忽略, 所以狀態儲存在該量詞的前面。

結合匹配優先量詞,來看乙個例子

假如我現在有這樣乙個字串

hello my name is "zhangsan", and my father name is "zhangsi"
如果現在我們要匹配前面引號裡面的zhangsan我們應該怎麼做,我們好像可以直接zhangsan,這樣,但是這只是個特例,我們的初衷是為了匹配引號中的東西。

如果我們用".*"來匹配呢?那匹配到的結果肯定是

"zhangsan", and my father name is "zhangsi"
這是為啥?

因為*是匹配優先的量詞啊,在進行匹配的時候,*肯定是會先嘗試匹配,它會將整個文字都匹配完, 當控制權來到"手上時,它交出最後乙個字元",此時匹配成功,所以匹配的結果是這個。

但是這不是我們想要的結果啊!那我們應該如何來匹配?答案是用忽略優先量詞".*?"

在開始匹配的時候,*?會因為是忽略優先而放棄匹配,然後控制權交給",發現匹配失敗,回溯,接著匹配,以此往復,當匹配到"時,匹配成功,匹配結果為 :

"zhangsan"
太好了!這是我們想要的結果!

我們發現,匹配優先量詞會先貪婪的把能匹配的都匹配了,然後最後再以大局為重被迫交出幾個字元,這樣看好像是從後往前來匹配的,而忽略優先量詞會懶惰的不想匹配,然後再以大局為重被迫匹配幾個字元,在這樣看好像是順序匹配的。

假如有一篇長篇大論,然而你只想匹配開頭的子串的話,你應該首先選擇忽略優先量詞,如果你只是想匹配後面的子串,你應該首先選擇匹配優先量詞

不妨在看乙個比較極端的例子

function targetstringfactory() 

return [originstr, ...attacharr].join("");

}let str = targetstringfactory();

console.time("greedy");

str.match(/.*[0-9]/);

console.timeend("greedy");

console.time("lazy");

str.match(/.*?[0-9]/);

console.timeend("lazy");

我只是想匹配開頭的abcd1234,後面跟著 1000000 個 a,這時候,我們把匹配優先量詞忽略優先量詞最乙個對比

greedy: 5.238ms

lazy: 0.113ms

發現忽略優先量詞確實比匹配優先量詞要快的多…

regex 以大局為重的匹配優先量詞

在正規表示式中有三個匹配優先的量詞,分別是 所謂匹配優先,其實就是日常說的貪婪,它們會盡可能的匹配更多的字元,換一種說法,它們一般會匹配大於下限,它們好像一群好久沒吃飽飯的窮苦人民,有東西吃,當然要盡可能吃的更多啊!比如說,現在有這樣乙個字串 hello man 如果我用.去匹配,得到的將會是hel...

關於 匹配優先 和 忽略優先

color green size large 為了更好的理解 匹配優先 和 忽略優先 我們可以這樣定義 匹配優先 可以理解為 貪婪匹配 或 非懶惰匹配 忽略優先 可以理解為 非貪婪匹配 或 懶惰匹配 size color color red size large 強調一點 表示式cat不是匹配以ca...

用Regex來忽略大小替換字串

string if string.isnullorwhitespace pattern continue console.write 模式說明匹配兩個連續反斜槓 字元。因為反斜槓字元被解釋為轉義符,每個反斜槓必須由另乙個反斜槓進行轉義。environment.machinename 匹配 envir...