了解RegExp類型:
ECMAScript通過(guò)RegExp類型來(lái)支持正則表達(dá)式。 var expression=/pattern/flags;
正則表達(dá)式的模式(pattern)部分:
可以是任何簡(jiǎn)單或復(fù)雜的正則表達(dá)式,可以包含字符類,限定符,分組,向前查找,反向引用。 關(guān)于正則表達(dá)式中各種特殊字符(如 /,^,$,/w,/b 等)的含義可以參考 MDN 正則表達(dá)式-特殊字符 的整理。這里我們簡(jiǎn)單介紹一下向前查找和反向引用。
向前查找:正則表達(dá)式向前使用一些字符而不移動(dòng)這些字符的位置,分為正向前預(yù)搜索也叫正向肯定查找( x(?=y) )與負(fù)向前預(yù)搜索也叫正向否定查找( x(?!y) )。
反向引用:標(biāo)識(shí)字符串中可以提供的重復(fù)字符或字符串,可以使用捕獲組反向引用匹配。帶編號(hào)的反向引用 /number number是正則表達(dá)式中捕獲組的序號(hào)位置。
1、表達(dá)式 /1~/9 解釋為反向引用而不是八進(jìn)制代碼。 //b(/w+)/s/1/.exec('s_ s_');//["s_ s_", "s_"]
2、如果多位表達(dá)式的第一個(gè)數(shù)字是8或者9(如 /80 或 /91 ),則該表達(dá)式將被解釋為文本。 //b(/w+)/s/80/.exec('s_ 800');//["s_ 80", "s_"]
3、對(duì)于編號(hào)為 /10 或更大值的表達(dá)式,如果存在與該編號(hào)對(duì)應(yīng)的反向引用,則將該表達(dá)式視為反向引用。否則將這些表達(dá)式解釋為八進(jìn)制。
/(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)xx/10/.exec('12345678910xx10');//["12345678910xx10", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]/(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)xx/11/.exec('12345678910xx10');//null
4、如果捕獲組嵌套捕獲組,捕獲組確定的順序是內(nèi)部從外到內(nèi),外部從左到右。來(lái)個(gè)代碼體會(huì)一下。
//b(/w+x(x))/s(/1)/.exec('s_xx s_xxSTOP');//["s_xx s_xx", "s_xx", "x", "s_xx"]
5、如果正則表達(dá)式包含對(duì)未定義的組成員的反向引用,則會(huì)發(fā)生分析錯(cuò)誤,根據(jù)語(yǔ)言的不同正則表達(dá)式引擎將引發(fā) ArgumentEXception 。對(duì)于javascript會(huì)返回null。//b(/w+)/s/2/.exec('s_ 8');//null
反向引用實(shí)例代碼:捕獲組捕獲到的內(nèi)容不僅可以在正則表達(dá)式外部通過(guò)程序進(jìn)行引用( RegExp.$n )也可以在正則表達(dá)式內(nèi)部進(jìn)行引用( /number ,這種引用方式就是反向引用)。
//表達(dá)連續(xù)三個(gè)相同的小寫,{2}應(yīng)用在/1身上/([a-z])/1{2}/.exec('aaa');//["aaa", "a"]復(fù)制代碼//一道有意思的正則問題/(/w)((?=/1/1/1)(/1))/.exec('aa bbbb');//["bb", "b", "b", "b"]/*這里捕獲組有三個(gè),$1為(/w)中的內(nèi)容,$2為((?=/1/1/1)(/1))中的內(nèi)容:需注意(?=/1/1/1)并不是捕獲組而是正則表達(dá)式的判斷條件,x(?=y)表示匹配x僅僅當(dāng)后面跟著y,判斷條件并不是匹配結(jié)果的一部分。所以現(xiàn)在$2的內(nèi)容為(/1)即‘b'。$3就是/1的內(nèi)容。返回的匹配項(xiàng)“bb”中的第一個(gè)'b'為"aa bbbb"中的第一個(gè)'b',第二個(gè)'b'為"aa bbbb"中的第二個(gè)'b'。*//(/w)(x(?=/1/1/1)(/1))/.exec('aa bxbbbcb');//["bxb", "b", "xb", "b"]//這里$2的內(nèi)容為(x(?=/1/1/1)(/1))中的內(nèi)容即x(/1);//其實(shí)上面兩種模式可以簡(jiǎn)化成/(/w)(?=/1/1/1)(/1)/表示匹配/w僅當(dāng)該/w后后面跟著三個(gè)/1,然后獲取的匹配項(xiàng)為該/w且其后再緊跟著/1的字符串。同理/(/w)x(?=/1/1/1)(/1)/復(fù)制代碼/(/w)((?=/1/1/1)(/2))/.exec('aa bbbbv');//["b", "b", "", ""]/*捕獲組$2為((?=/1/1/1)(/2))中的內(nèi)容,由于此時(shí)還未執(zhí)行完捕獲組$2處的匹配,所以/2表示""。$3即為/2的內(nèi)容還是""。所以這條匹配被解釋為返回/w且其后緊跟3個(gè)該/w的字符串,返回/w+''就只返回'b'了。*/
正則表達(dá)式的標(biāo)志位(flags)部分:
可以帶有一個(gè)或多個(gè)標(biāo)志,用以表明正則表達(dá)式的行為。
1、g:表示全局模式,模式將被應(yīng)用于所有字符串,而非在發(fā)現(xiàn)第一個(gè)匹配項(xiàng)時(shí)立即停止。 'cat mat bat'.replace(/.(?=at)/g,'A');//"Aat Aat Aat"
2、i:不區(qū)分大小寫模式,在確定匹配項(xiàng)時(shí)忽略模式與字符串的大小寫。 'cAt mat bAt'.replace(/a/gi,'B');//"cBt mBt bBt"
3、m:多行模式,在到達(dá)一行文本末尾時(shí)還會(huì)繼續(xù)查找下一行中是否存在與模式匹配的項(xiàng)。
var str='cat/nmat/nbat';str.replace(/at/gm,'AB');/*"cABmABbAB"*/
正則表達(dá)式中的元字符部分:
在模式中使用這些元字符時(shí)必須轉(zhuǎn)義,如果想要匹配的字符串中包含這些字符,就需要對(duì)他們進(jìn)行轉(zhuǎn)義。
( [ { / ^ $ | ) ? * + . ] }//匹配"[bc]at"http://[bc/]at/.exec("xx[bc]at");//["[bc]at"]//匹配".at"http://.at/.exec("xx.at");//[".at"]
創(chuàng)建正則表達(dá)式:
字面量形式:形如 var expression=/pattern/flags;
RegExp構(gòu)造函數(shù):兩個(gè)參數(shù)(要匹配的字符串模式,可選的標(biāo)志字符串),不能把正則表達(dá)式字面量傳遞給構(gòu)造函數(shù),雖然即使這樣寫了也不會(huì)報(bào)錯(cuò)。可以使用字面量定義的任何表達(dá)式都可以使用構(gòu)造函數(shù)來(lái)定義。如下:
var p=/[bc]at/;new RegExp('[bc]at');// /[bc]at/
1、當(dāng)不傳任何參數(shù)或參數(shù)一為空字符串時(shí), new RegExp();// /(?:)/ 或 new RegExp('');// /(?:)/ ,表示匹配 "" 但不記住匹配項(xiàng)( "" 其實(shí)就是 ":" 之后的空串,不記住x匹配項(xiàng)的規(guī)則為(?:x)),所以在匹配任何字符串時(shí)都返回 [""] 。所以由此可以猜想一下javascript正則引擎內(nèi)部機(jī)制應(yīng)該是默認(rèn)匹配 "" 且不記住該匹配項(xiàng),除非顯式聲明在 ":" 之后的需要匹配的字符串,加上 "(?:)" 顯式聲明不記住匹配項(xiàng)。
2、由于構(gòu)造函數(shù)模式參數(shù)是字符串,所以某些情況下(是指那些已經(jīng)轉(zhuǎn)義過(guò)的字符)對(duì)字符進(jìn)行雙重轉(zhuǎn)義(即在字面量形式的單重轉(zhuǎn)義再來(lái)一層轉(zhuǎn)義)。某些情況下當(dāng)然也可以進(jìn)行單重轉(zhuǎn)移( new RegExp('/w');// /w/ )。注意'/'比較特殊,在字符串中也需要進(jìn)行轉(zhuǎn)義。
var p=///n/;//轉(zhuǎn)義/,字符"/"在字符串中常需要被轉(zhuǎn)義為"http://"p.exec("http://nxx");//["/n"]var p=new RegExp("http:////n");// ///n/ 如果想獲得正則表達(dá)式字面量為///n/,需要在正則表達(dá)式中再來(lái)一層轉(zhuǎn)義p.exec('//nxx');//["/n"] 注意被匹配的字符串'/nxx'中/n的/也被轉(zhuǎn)義了new RegExp('//n').exec("/n");// [""]/*RegExp('//n')返回//n/,即意思匹配換行符*/new RegExp('/n').exec("/n");//[""]/*new RegExp('/n')返回// ,表示并沒有進(jìn)行轉(zhuǎn)義,而是返回字面量//,意思匹配換行符*/
3、下面給出一些單重,雙重轉(zhuǎn)義模式的參考:第幾次轉(zhuǎn)義在表中已標(biāo)出,單代表第一次轉(zhuǎn)義,雙代表在已經(jīng)有的轉(zhuǎn)義的基礎(chǔ)上再進(jìn)行的轉(zhuǎn)義。
RegExp的實(shí)例屬性:
通過(guò)實(shí)例的屬性可以獲取有關(guān)模式的各種信息
global :布爾值,表示是否設(shè)置了g標(biāo)志。
ignoreCase :布爾值,表示是否設(shè)置了i標(biāo)志。
multiline :布爾值,表示是否設(shè)置了m標(biāo)志。
lastIndex :整數(shù),表示開始搜索下一個(gè)匹配項(xiàng)的字符位置,從0算起。前提是設(shè)置g標(biāo)志時(shí)才會(huì)有用。
source :正則表達(dá)式的字符串標(biāo)志,按照字面量形式而非構(gòu)造函數(shù)中的字符串模式返回字符串。
new RegExp('////w');// ///w/ 返回自面量形式正則表達(dá)式new RegExp('////w').source;// "http://w" 字符串
RegExp的實(shí)例方法:
exec():該方法是專門為捕獲組而設(shè)計(jì)的,參數(shù)為要匹配的字符串,返回包含第一個(gè)匹配項(xiàng)信息和可能有的捕獲組的數(shù)組,若未匹配到返回 null 。(返回的雖然是 Array 的實(shí)例,但還包含兩個(gè)額外的屬性: index 表示匹配項(xiàng)在字符串中的位置, input 表示應(yīng)用正則表達(dá)式的字符串)
var arr=new RegExp('////(w)').exec('//w');// ["/w", "w"]arr;// ["/w", "w"]arr.index;//0arr.input;// "/w" 即exec()里的內(nèi)容
exec() 和 match() 方法的區(qū)別:
1、對(duì)于 exec() 而言,即使在模式中設(shè)置了全局標(biāo)志g,它每次也只返回一個(gè)匹配項(xiàng);字符串的 match() 方法在設(shè)置g的時(shí)候可以返回全部匹配項(xiàng)而沒有捕獲組且返回的數(shù)組沒有index和input屬性。
2、對(duì)于exec()而言可以返回捕獲組,但match()在沒有全局g標(biāo)志時(shí)才能返回捕獲組,此時(shí)match()返回的數(shù)組有index和input屬性。
//返回全局匹配項(xiàng)演示比較var arr='ababcdab'.match(/ab/g);// ["ab", "ab", "ab"]arr.index; // undefinedarr.input; // undefined/ab/g.exec('ababcdab');// ["ab"]//捕獲組演示比較,match()方法和有無(wú)設(shè)置全局g標(biāo)志有關(guān)'ababcdab'.match(/a(b)/g);// ["ab", "ab", "ab"]var arr='ababcdab'.match(/a(b)/);// ["ab", "b"]arr.index;// 0arr.input;// 'ababcdab'/a(b)/g.exec('ababcdab');// ["ab", "b"]
3、所以在選擇使用方法的時(shí)候要先考慮好側(cè)重該方法的哪方面功能,在不設(shè)置全局標(biāo)志g的情況下,在同一個(gè)字符串上多次調(diào)用exec()則總是返回第一個(gè)匹配項(xiàng)的信息,而在設(shè)置全局標(biāo)志的情況下,每次調(diào)用exec()則都會(huì)在字符串中沿著上次查找的位置往后繼續(xù)查找新的匹配項(xiàng)。
//未設(shè)全局,每次從頭開始查找var p=/a/;var str='ababa';var a=p.exec(str);// ["a"];var b=p.exec(str);// ["a"];a==b;// falsea.index==b.index;// true//設(shè)置全局,沿著上次位置繼續(xù)查找新匹配var p=/a/g;var str='ababa';var a=p.exec(str);// ["a"]a.index;// 0var b=p.exec(str);// ["a"]b.index;// 2
test():接收字符串參數(shù),在模式與字符串參數(shù)匹配情況下返回 true ,否則返回 false 。常被用在 if() 中當(dāng)判斷條件。
var text="000-000-000";var p=/((/d{3})-)/1*/2/; if(p.test(text)){ console.log('匹配成功');}
RegExp 實(shí)例繼承 Object 的 toLocaleString() 和 toString() 方法都會(huì)返回正則表達(dá)式的字面量形式的字符串,與如何創(chuàng)建正則表達(dá)式的方式無(wú)關(guān)。 valueOf() 則返回正則表達(dá)式字面量本身。
var p=//[new/]bi/;p.toLocaleString();// "http://[new/]bi/"p.toString();// "http://[new/]bi/"p.valueOf();// //[new/]bi/var p=new RegExp('//[new//]bi');p.toLocaleString();// "http://[new/]bi/"p.toString();// "http://[new/]bi/"p.valueOf();// //[new/]bi/
RegExp的構(gòu)造函數(shù)屬性:
構(gòu)造函數(shù)本身包含一些屬性(靜態(tài)屬性),這些屬性適用于作用域中的所有表達(dá)式,并且基于所執(zhí)行的最近一次正則表達(dá)式操作而變化。有長(zhǎng)屬性名(如下代碼)和短屬性名(即$前綴形式,由于這些符號(hào)大多不是有效的ECMAScript標(biāo)識(shí)符,所以不能直接在 RegExp 構(gòu)造函數(shù)上以 "." 的方式訪問,而要通過(guò)方括號(hào)語(yǔ)法來(lái)訪問)兩種方式訪問這些屬性
/(.)hort/g.exec('this is a short day');// ["short", "s"]//最近一次要匹配的字符串RegExp.input;// "this is a short day" 或RegExp["$_"]訪問;//最近一次的匹配項(xiàng)RegExp.lastMatch;// "short" 或RegExp["$&"]訪問;//在最近一次要匹配的字符串中的最近一次匹配項(xiàng)之前的文本 RegExp.leftContext;// "this is a " 或RegExp["$`"]訪問;//在最近一次要匹配的字符串中的最近一次匹配項(xiàng)之后的文本 RegExp.rightContext;// " day" 或RegExp["$'"]訪問;//最近一次(最后一次)匹配的捕獲組RegExp.lastParen;// "s" 或RegExp["$+"]訪問;
捕獲組訪問屬性:還有9個(gè)用于存儲(chǔ)捕獲組的構(gòu)造函數(shù)屬性,訪問語(yǔ)法是 RegExp.$n ,其中n取值1~9,用于獲取第n個(gè)匹配的捕獲組。在調(diào)用 exec() , test() 或 match() 等正則系列方法時(shí)這些屬性會(huì)被自動(dòng)填充。
var text="this is a short summer";var pattern =/(..)or(.)/g;if(pattern.test(text)){ console.log(RegExp.$1); // sh console.log(RegExp.$2); // t }
模式的局限性:
缺少一些高級(jí)正則表達(dá)式的特性,如不支持向后查找,命名的捕獲組(形如 /k<name> 引用之前名為 name 的捕獲組的字符串)等。
推薦專題: 《javascript正則表達(dá)式使用說(shuō)明》
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注