上一篇:常用正則表達(dá)式
正則捕獲的懶惰性及解決方案
-
正則捕獲
? :把一個(gè)字符串和正則匹配的部分獲取到
? [正則方法:]
? exec:捕獲
? test:匹配
? [字符串方法實(shí)現(xiàn)正則捕獲:]
? replace
? split
? match
? ……
-
基于EXEC可以實(shí)現(xiàn)正則的捕獲
如果當(dāng)前正則和字符串不匹配,捕獲的結(jié)果是null
-
如果匹配捕獲的結(jié)果就是一個(gè)數(shù)組
- 索引0:大正則捕獲的內(nèi)容
- index:正則捕獲的起始索引
- input:原始操作的字符串
let str='shang2019xiaolin2020' let str1='shangxiaolin' let reg=/\d+/ console.log(reg.test(str))//true console.log(reg.test(str1))//false //正則EXEC捕獲 console.log(reg.exec(str))//["2019", index: 5, input: "shang2019xiaolin2020", groups: undefined] console.log(reg.exec(str1))//null
-
執(zhí)行一次exec只能捕獲到一個(gè)和正則匹配的內(nèi)容,其余內(nèi)容還沒有捕獲到(執(zhí)行多次奋渔,也沒有卵用,依然只會(huì)捕獲相同的內(nèi)容)
//正則EXEC捕獲 console.log(reg.exec(str))//["2019", index: 5, input: "shang2019xiaolin2020", groups: undefined] //正則EXEC捕獲 console.log(reg.exec(str))//["2019", index: 5, input: "shang2019xiaolin2020", groups: undefined]
-
正則的捕獲天生具備懶惰性:只能捕獲第一個(gè)匹配的內(nèi)容捎稚,剩余的默認(rèn)捕獲不到(解釋了上述3)
-
懶惰性的原因:
-
lastIndex的值沒有變:正則在捕獲的時(shí)候奈揍,lastIndex為下一次在字符串中開始查找的索引
//=>LAST-INDEX的值不變垦页,導(dǎo)值懶惰性 console.log(reg.lastIndex)//=>0 console.log(reg.exec(str))//["2019", index: 5, input: "shang2019xiaolin2020", groups: undefined] console.log(reg.lastIndex)//=>0 console.log(reg.exec(str))//["2019", index: 5, input: "shang2019xiaolin2020", groups: undefined]
-
即使我們手動(dòng)修改lastIndex掌唾,然而也沒有卵用
reg.lastIndex=9 console.log(reg.lastIndex)//=>9 console.log(reg.exec(str))//["2019", index: 5, input: "shang2019xiaolin2020", groups: undefined]
-
-
-
解決正則懶惰性給正則加修飾符g
- 加G是唯一解決方案放前,否則永遠(yuǎn)不能夠全局匹配捕獲
let str='shang2019xiaolin2020' //加修飾符g let reg=/\d+/g; //g: 全局捕獲 console.log(reg.lastIndex)//0 console.log(reg.exec(str))["2019", index: 5, input: "shang2019xiaolin2020", groups: undefined] console.log(reg.lastIndex)//9 console.log(reg.exec(str))["2020", index: 5, input: "shang2019xiaolin2020", groups: undefined] console.log(reg.lastIndex)//20 console.log(reg.exec(str))//null console.log(reg.lastIndex)//0 console.log(reg.exec(str))["2019", index: 5, input: "shang2019xiaolin2020", groups: undefined]
-
match()捕獲:(字符方法:只需一次執(zhí)行就可以捕獲所有匹配的內(nèi)容)
let str='shang2019xiao2020lin2021' let reg=/\d+/g; str.match(reg)// ["2019", "2020", "2021"]
-
封裝(match()原理)
需求:原: 全局捕獲想要捕獲到所有匹配到的內(nèi)容需一次一次的執(zhí)行exec(太麻煩)
現(xiàn): 我們需封裝一個(gè)只需一次執(zhí)行就可以捕獲所有匹配的內(nèi)容的程序let str='shang2019xiao2020lin2021' let reg=/\d+/g; RegExp.prototype.myExecAll=functioin(str){ //this: reg(當(dāng)前操作的正則) //str:傳入的需要捕獲的字符串 //執(zhí)行EXEC開始捕獲,具體捕獲多少次不定糯彬,但是一直到捕獲不到內(nèi)容(null)為止凭语,期間把捕獲到的內(nèi)容存儲(chǔ)到數(shù)組中即可 if(!this.global){//=>為防止出出現(xiàn)死循環(huán),我們需要檢測(cè)一下正則是否加G,沒有加G只需捕獲一次返回結(jié)果即可 //global:正則屬性撩扒,加'G'global為true.沒有'G'global為false return this.exec(str) } let result=[]; let valAry=this.exec(str); while(valAry){ result.push(valAry[0]);//把每一次捕獲到的結(jié)果第一項(xiàng)存儲(chǔ)到容器中 valAry=this.exec(str); } return result }; console.log(reg.myExecAll(str))//["2019", "2020", "2021"]
下一篇:正則捕獲的貪婪性及解決方案
?