正則有一個最大的好處就是效率高,對於一些復雜的字符串匹配的問題,如果用原生原生API解決比較繁瑣,可以考慮用正則表達式來匹配。
這幾天正在研究正則的循環匹配的問題,分享出來看看。
分組實現循環匹配
正則表達式中的分組是一個很重要的功能,有了它,我們可以進行分組的查詢替換操作,下面是例子👇
var reg = /(abc|hij)/g;
"abcdefghij".replace(reg,"-");
//它會匹配分組里面的abc或hij 替換成-,輸出結果 :-defg-
當正則表達式中有分組時,JS正則引擎實現了一個 美元符號+數字 ($1,$2.$3 … )按順序匹配對應到的分組。
var reg = /(abc)(def)/g
"abcdef".replace(reg,"$2$1")
"defabc"
//這個例子就是abc->$1 def->$2 ,然后把匹配的分組替換了。
再進一步,如果分組中存在多個匹配(貪婪模式)時,光寫$1,$2..就滿足不了需求了。
舉個例子:銀行卡四位空格的處理
var reg = /(\d{4})+?/g
"6226600000000001".replace(reg,"$1 ")
/*
這個$1匹配的是對應的循環出來的分組 不僅僅是第一分組,在這里的含義就是循環出來的每一個分組
"6226 6000 0000 0001"
*/
也就是說,如果正則想對貪婪模式的分組做處理時,譬如說替換,插入等操作時。 $1 就代表每次循環出來的分組
記一些正則比較冷門的知識。
//把相同的字符區分開來 aabbcccdddd -> "aa bb ccc dddd"
"aaabbcccdddd".match(/([a-z])\1+/g)
//輸出:["aaa", "bb", "ccc", "dddd"]
//\n -> "斜杠后面帶數字意味着相同的字符連續匹配n次,如果是連續匹配2次就是 \1 兩次以上就是 \1+"
后向先行斷言 (匹配到字符串后面的位置)
按上面的銀行卡四位空格的的要求:我們寫下如下的正則表達式
"1111222233334444".replace(/(?<=(^(\d{4})+))(?<!$)/g," ")
后向先行斷言概念:?<= 這個api 是匹配后面位置的 就是說 匹配到所在字符的后面位置。
舉個例子:
//aaabbbccc 需要匹配aaa 后面的所有內容
"aaabbbccc".match(/(?<=aaa).+/g)
上面的銀行卡四位空格的 可以分步驟來分析。
- 第一步:先得出第一個空格
/(?<=^(\d{4}))/得出來:1111 222233334444 - 第二步:得出其他的空格,也就是分組多加個
+號 進行貪婪匹配,並且全局搜索匹配(?<=(^(\d{4})+))/g - 第三步:我們發現最末尾的也會多出來空格,這個空格是我們不想看到的。所以最后的末尾我們不去匹配。
/(?<=(^(\d{4})+))(?<!$)/g
