正則表達式中的exec和match方法的區別
字符串的正則方法有:match()、replace()、search()、split()
正則對象的方法有:exec()、test()
1.match
match方法屬於String正則表達方法.
語法: str.match(regexp)
str:要進行匹配的字符串. regexp:一個正則表達式(或者由RegExp()構造成的正則表達式)
match的用法主要區分就是,正則表達式是否有全局標示g.
1)如果有g全局標志,那么返回的數組保存的是,所有匹配的內容,不包過子匹配。
2)如果沒有g全局標志,那么返回的數組arr.arr[0]保存的是完整的匹配.arr[1]保存的是第一個括號里捕獲的字串,依此類推arr[n]保存的是第n個括號捕獲的內容.也就是當包含有全局的標志時則返回的結果第一個是正確匹配的結果,后面依次是子匹配的結果。
2.exec
與match方法不同exec屬於正則表達式的方法.
語法:var result1 = regexp.exec(str);
regexp:正則表達式(可以直接定義也可以利用RegExp的方式定義) str:要匹配的字串
exec與match的關聯就是exec(g有沒有都無影響)就等價於不含有g全局標志的match.即返回數組arr[0]為匹配的完整串.其余的為括號里捕獲的字符串(當含有子匹配時).
1、如果exec執行的正則表達式沒有子表達式(小括號內的內容,如/abc(\s*)/中的(\s*) ),如果有匹配,就返回第一個匹配的字符串內容,此時的類數組中的第一個元素為匹配的內容,(類數組中還包含有index:匹配字符串在原始字符串中的位置,input:輸入的字符串)如果沒有匹配返回null;
var reg = new RegExp("abc") ; var str = "3abc4,5abc6"; alert(reg.exec(str)); alert(str.match(reg));
執行如上代碼,你會發現兩者內容均為一樣:abc,此時exec 中沒有子表達式同時兩者均為非全局的匹配
********子表達式捕獲的內容就是指的第一個完全匹配的字符串中在表達式匹配的部分:
var a=/^([^.]*)(?:\.(.+)|)$/; var str="click.41646ass.sss"; var b=a.exec(str); console.log(b)
輸出["click.41646ass.sss", "click", "41646ass.sss"],正則表達式中共有三個括號但是第二個大括號采用?:的方法取消了捕獲,也就是不輸出匹配字符串中該子表達式匹配的部分,click對應([^.]*),41646ass.sss對應(.+),所以當為a=/^([^.]*)(\.(.+)|)$/時輸出的結果為:["click.41646ass.sss", "click",".41646ass.sss" ,"41646ass.sss"],.41646ass.sss對應於(?:\.(.+)|)
2、當exec和match中具有相同的子表達式且為非全局匹配時兩者的輸出也是相同的,同時輸出的數組中含有的多個元素。
var str="visit W3cschool a W3cschool bull"; var reg=new RegExp("W3c(school)"); var b=reg.exec(str); console.log(b); console.log(str.match(/W3c(school)/));
執行上訴代碼的結果為W3cschool,school
3、當為全局匹配時
var str="visit W3cschool a W3cschool bull"; var reg=new RegExp("W3cschool",'g'); var b=reg.exec(str); console.log(b); console.log(str.match(/W3cschool/g));
Exec中沒有子表達式其輸出為W3cschool,其輸出只一個,match全局匹配時其輸出元素中將包含所有的匹配項,其輸出為W3cshcool,W3cschool
總結為:
(1)exec中不管是不是全局的匹配,只要沒有子表達式,其返回的都只有一個元素,如果是全局匹配,可以利用lastIndex進行下一個匹配,匹配成功后lastIndex的值將會變為上次匹配的字符的最后一個位置的索引。在設置g屬性后,雖然匹配結果不受g的影響,返回結果仍然是一個數組(第一個值是第一個匹配到的字符串,以后的為分組匹配內容),但是會改變index和 lastIndex等的值,將該對象的匹配的開始位置設置到緊接這匹配子串的字符位置,當第二次調用exec時,將從lastIndex所指示的字符位置 開始檢索。同樣match方法在設置了g屬性后,也會改變index和lastIndex的值,但是是一次性的。無法像exec那樣能逐過程累積,因此無 法累積獲取下一次檢索的位置。
var patt = new RegExp('ab', 'g'); var str = 'abcdef12ab34cd56ef'; var ret; while((ret = patt.exec(str))!=null) { document.write(ret+"</br>"); document.write("ret.input="+ret.input+"</br>"); document.write("ret.index="+ret.index+"</br>"); document.write("RegExp.lastIndex ="+patt.lastIndex +"</br>"); }
注意:當沒有全局的變量g時,由於index和lastindex的值不會變化(除非手動修改),則會導致每次的陪匹配都是從字符串的頭開始的,所以只要字符串中有匹配,就會導致死循環,當時設置g后,會自動改變前面的兩個屬性,會依次向后匹配直到沒有匹配項退出循環
輸出結果:
ab ret.input=abcdef12ab34cd56ef ret.index=0 RegExp.lastIndex =2 ab ret.input=abcdef12ab34cd56ef ret.index=8 RegExp.lastIndex =10
(2)Match在非全局匹配時其他幾種情況下(有無子匹配的情況下)的返回結果和exec是相同的,在全局匹配時其將返回包含所有匹配項的數組(其中不包含子匹配)。
(3)exec返回的是類數組而match返回的則是數組