RegExp類型
ECMAScript通過RegExp類型來支持正則表達式亏拉。使用如下語法,可以創(chuàng)建一個正則表達式逆巍。
var expression = / pattern / flags;
其中的模式(pattern)部分可以說任何簡單的或復雜的正則表達式及塘,可以包含字符類、限定符锐极、分組笙僚、向前查找以及反向引用。每個正則表達式都可帶有一或多個標志(flags),用以表明正則表達式的行為灵再。
正則表達式的匹配模式支持下列3個標志肋层。
- g:表示全局(global)模式,即模式將被應用于所有字符串翎迁,而非在發(fā)現(xiàn)第一個匹配項時立即停止
- i:表示不區(qū)分大小寫(casi-insensitive)模式槽驶,即在確定匹配項時忽略模式與字符串的大小寫
- m:表示多行(multiline)模式,即在到達一行文本末尾時還會繼續(xù)查找下一行中是否存在與模式匹配的項鸳兽。
/**
* 匹配字符串中多有"at"的實例
*/
var parttern1 = /at/g;
/**
* 匹配第一個"bat"或"cat"掂铐,不區(qū)分大小寫
*/
var parttern2 = /[bc]at/i;
/**
* 匹配所有以"at"結(jié)尾的3個字符的組合,不區(qū)分大小寫
*/
var parttern3 = /.at/gi;
模式中使用的所有元字符都必須轉(zhuǎn)義揍异。正則表達式的元字符包括:
( [ { \ ^ $ | ) ? * + . ] }
這些元字符在正則表達式中都有一或多種用途全陨,因此想要匹配字符串中包好的這些字符,就必須對它們就行轉(zhuǎn)義衷掷。如:
/**
* 匹配第一個"bat"或"cat"辱姨,不區(qū)分大小寫
*/
var parttern1 = /[bc]at/i;
/**
* 匹配第一個"[bc]at",不區(qū)分大小寫
*/
var parttern2 = /\[bc\]at/i;
/**
* 匹配所有以"at"結(jié)尾的3個字符的組合戚嗅,不區(qū)分大小寫
*/
var parttern3 = /.at/gi;
/**
* 匹配所有以".at"結(jié)尾的3個字符的組合雨涛,不區(qū)分大小寫
*/
var parttern3 = /\.at/gi;
前面舉的這些例子都是以字面量形式來定義的正則表達式枢舶。另一種創(chuàng)建正則表達式的方式是使用RegExp構(gòu)造函數(shù),它接收兩個參數(shù):一個是要匹配的字符串模式替久,另一個是可選的標志字符串凉泄。
/**
* 匹配第一個"bat"或"cat",不區(qū)分大小寫
*/
var parttern1 = /[bc]at/i;
var parttern2 = new RegExp("[bc]at","i");
傳遞給RegExp構(gòu)造函數(shù)的兩個參數(shù)都是字符串蚯根。
由于RegExp構(gòu)造函數(shù)的模式參數(shù)是字符串后众,所以在某些情況下要對字符進行雙重轉(zhuǎn)義。
/\[bc\]at/——"\\\[bc\\\]at"
/\\.at/——"\\\\.at"
/name\/age/——"name\\\\/age"
/\d.\d{1,2}/——"\\\\d.\\\\d{1,2}"
-
/\w\hello\\123/——"\\\\w\\\\hello\\\\123"
使用正則表達式字面量和使用RegExp構(gòu)造函數(shù)的正則表達式不一樣颅拦。在ECMAScript3中蒂誉,正則表達式字面量始終會共享同一個RegExp實例,而使用構(gòu)造函數(shù)創(chuàng)建的每一個新RegExp實例都是一個新實例距帅。
var re = null,
i;
for(i=0; i<10; i++){
re = /cat/g;
re.test("catastrophe");//
}
for(i=0; i<10; i++){
re = new RegExp("cat", "g");
re.test("catastrophe");
}
在第一個循環(huán)中右锨,即使是循環(huán)體中指定的,但實際上只為/cat/創(chuàng)建了一個RegExp實例碌秸。由于實例屬性不會重置绍移,所以在循環(huán)中再次調(diào)用test()方法會失敗。這是因為第一次調(diào)用test()找到了"cat"哮肚,但第二次調(diào)用是從索引為3的字符(上一次匹配的末尾)開始的登夫,所以就找不到他了。由于會測試到字符串末尾允趟,所有下一次在調(diào)用test()就又重頭開始了恼策。
第二個循環(huán)使用RegExp構(gòu)造函數(shù)在每次循環(huán)匯總創(chuàng)建正則表達式。因為每次迭代都會創(chuàng)建一個新的RegExp實例潮剪,所以每次調(diào)用test()都=都會返回true庙楚。
-
1. RegExp實例屬性
RegExp的每個實例都具有下列屬性扰付,通過這些屬性可以取得有關(guān)這些模式的各種信息揭璃。
- global:布爾值推汽,鄙視是否設(shè)置了g標志
- ignoreCase:布爾值,表示是否設(shè)置了i標志
- lastIndex:整數(shù)弧蝇,表示開始搜索下一個匹配項的字符位置碳褒,從0算起
- multiline:布爾值,表示是否設(shè)置了m標志看疗。
- source:正則表達式的字符串表示沙峻,按照字面量形式而非傳入構(gòu)造函數(shù)中的字符串模式返回。
通過 這些屬性可以獲知一個正則表達式的各方面信息两芳,單曲全額沒有多大用處摔寨,因為這些信息包含在模式聲明中。
var pattern1 = /\[bc\]at/i;
alert(pattern1.glable); //false
alert(pattern1.ignoreCase); //true
alert(pattern1.multiline); //false
alert(pattern1.lastIndex); //0
alert(pattern1.source); //"\[bc\]at"
var pattern2 = new RegExp("\\[bc\\]at","i");
alert(pattern2.glable); //false
alert(pattern2.ignoreCase); //true
alert(pattern2.multiline); //false
alert(pattern2.lastIndex); //0
alert(pattern2.source); //"\[bc\]at"
-
2. RegExp實例方法
RegExp對象的主要方法是exec(),該方法是專門為捕獲組而設(shè)計的怖辆。
exec()接受一個參數(shù)是复,即要應用模式的字符串删顶,然后返回包含第一個匹配項信息的數(shù)組;或者在沒有匹配項的情況下返回null淑廊。返回數(shù)組雖然是Array的實例逗余,但包含兩個額外的屬性:index和input。其中蒋纬,index表示匹配項在字符串中的位置猎荠,而input表示應用正則表達式的字符串坚弱。在數(shù)組中蜀备,第一項是與整個模式匹配的字符串,其他項是與模式中的捕獲組匹配的字符串(如果模式中沒有捕獲組荒叶,則該數(shù)組只包含一項)碾阁。
var text = "mom and dad and baby";
var pattern = /mom(and dad(and baby)?)?/gi;
var matches = pattern.exec(text);
alert(matches.index); //0
alert(matches.input); //"mom and dad and baby"
alert(matches[0]); //"mom and dad and baby"
alert(matches[1]); //"and dad and baby"
alert(matches[2]); //"and baby"
在這個例子中包含兩個捕獲組。組內(nèi)部的捕獲組匹配"and baby",而包含它的捕獲組匹配"and baby"或者"and dad and baby"些楣。當把字符串傳入exec()方法中后脂凶,發(fā)現(xiàn)了一個匹配項。因為整個字符串本身與模式匹配愁茁,所以返回的數(shù)組matchs的index屬性值為0蚕钦。數(shù)組中的第一項是匹配的整個字符串,第二項包含與第一個捕獲組匹配的內(nèi)容鹅很,第三項包含與第二個捕獲組匹配的內(nèi)容嘶居。
對于exec()方法而言,即使在模式中設(shè)置了全局標志(g)促煮,它每次也只會返回一個匹配項邮屁。在不設(shè)置全局標志的情況下,在同一個字符串上多次調(diào)用exec()將始終返回第一個匹配項的信息菠齿。而在設(shè)置全局標志的情況下佑吝,每次調(diào)用exex()則都會在字符串中繼續(xù)查找新匹配項,如:
var text = "cat, bat, sat, fat";
var pattern1 = /.at/;
var matches = pattern1.exec(text);
alert(matches.index); //0
alert(matches[0]); //cat
alert(pattern1.lastIndex); //0
matches = pattern1.exec(text);
alert(matches.index); //0
alert(matches[0]); //cat
alert(pattern1.lastIndex); //0
var pattern2 = /.at/g;
var matches = pattern2.exec(text);
alert(matches.index); //0
alert(matches[0]); //cat
alert(pattern2.lastIndex); //3
matches = pattern2.exec(text);
alert(matches.index);//5
alert(matches[0]); //bat
alert(pattern2.lastIndex); //8
test()方法绳匀,它接受一個字符串參數(shù)芋忿。在模式與該參數(shù)匹配的情況下返回true,否則返回false疾棵。在指向知道目標字符傳與某個模式是否匹配戈钢,但不需要知道其文本內(nèi)容的情況下,使用這個方法非常方便陋桂。test()方法經(jīng)常被用作if語句中逆趣。
var text = "000-00-0000";
var pattern = /\d(3)-\d(2)-d(4)/;
if (pattern.test(text)) {
alert('The pattern was matched.');
}
這種方法經(jīng)常出現(xiàn)在驗證用戶輸入的情況下。
RegExp實例繼承的toLocaleString()和toString()方法都會返回正則表達式的字面量嗜历,與創(chuàng)建正則表達式的方式無關(guān)宣渗。如:
var pattern = new RegExp("\\[bc\\]at","gi");
alert(pattern.toString()); // /\[bc\]at/gi
alert(pattern.toLocaleString()); // /\[bc\]at/gi
正則表達式的valueOf返回正則表達式本身抖所。
- 3. RegExp構(gòu)造函數(shù)屬性
RegExp構(gòu)造函數(shù)包含一些屬性,這些屬性適用于作用域中的所有正則表達式痕囱,并且基于所執(zhí)行的最近一次正則表達式操作而變化田轧。可以通過兩種方式訪問它們鞍恢。
- input($_):最近一次要匹配的字符串
- lastMatch($&):最近一次的匹配項
- lastParen($+):最近一次匹配的捕獲組
- lastContext($`):input字符串中l(wèi)astMatch之前的文本
- multiline($*):布爾值傻粘,表示是否所有表達式都使用多行模式
- rightContext($'):Input字符串中l(wèi)astMatch之后的文本
使用這些操作可以從exec()或test()執(zhí)行的操作中提取更具體的信息。
var text = "this has been a short summer";
var pattern = /(.)hort/g;
if (pattern.test(text)) {
alert(RegExp.input); //this has been a short summer
alert(RegExp.leftContext); //this has been a
alert(RegExp.rightContext); //summer
alert(RegExp.lastMatch); //short
alert(RegExp.lastParen); //s
alert(RegExp.multiline); //false
}
var text = "this has been a short summer";
var pattern = /(.)hort/g;
if (pattern.test(text)) {
alert(RegExp.$_); //this has been a short summer
alert(RegExp["$`"]); //this has been a
alert(RegExp["$'"]); //summer
alert(RegExp["$&"]); //short
alert(RegExp["$+"]); //s
alert(RegExp["$*"]); //false
}
還有多達9個用于存儲捕獲組的構(gòu)造函數(shù)屬性帮掉。訪問這些屬性的語法是RegExp.$1,RegExp.$2,...RecExp.$9,分別用于存儲第一弦悉,第二...第九個匹配的捕獲組。在調(diào)用exec()后test()方法是蟆炊,這些屬性會被自動填充稽莉。
var text = "this has been a short summer";
var pattern = /(..)or(.)/g;
if (pattern.test(text)) {
alert(RegExp.$1); //sh
alert(RegExp.$2); //t
}