JavaScript引用類型——RegExp類型

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
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市涩搓,隨后出現(xiàn)的幾起案子污秆,更是在濱河造成了極大的恐慌,老刑警劉巖昧甘,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件良拼,死亡現(xiàn)場離奇詭異,居然都是意外死亡充边,警方通過查閱死者的電腦和手機庸推,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來痛黎,“玉大人予弧,你說我怎么就攤上這事『ィ” “怎么了掖蛤?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長井厌。 經(jīng)常有香客問我蚓庭,道長,這世上最難降的妖魔是什么仅仆? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任器赞,我火速辦了婚禮,結(jié)果婚禮上墓拜,老公的妹妹穿的比我還像新娘港柜。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布夏醉。 她就那樣靜靜地躺著爽锥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪畔柔。 梳的紋絲不亂的頭發(fā)上氯夷,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天,我揣著相機與錄音靶擦,去河邊找鬼腮考。 笑死,一個胖子當著我的面吹牛玄捕,可吹牛的內(nèi)容都是我干的踩蔚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼桩盲,長吁一口氣:“原來是場噩夢啊……” “哼寂纪!你這毒婦竟也來了席吴?” 一聲冷哼從身側(cè)響起赌结,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎孝冒,沒想到半個月后柬姚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡庄涡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年量承,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片穴店。...
    茶點故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡撕捍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出泣洞,到底是詐尸還是另有隱情忧风,我是刑警寧澤,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布球凰,位于F島的核電站狮腿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏呕诉。R本人自食惡果不足惜缘厢,卻給世界環(huán)境...
    茶點故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望甩挫。 院中可真熱鬧贴硫,春花似錦、人聲如沸伊者。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至贪绘,卻和暖如春兑牡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背税灌。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工均函, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人菱涤。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓苞也,卻偏偏與公主長得像,于是被迫代替她去往敵國和親粘秆。 傳聞我的和親對象是個殘疾皇子如迟,可洞房花燭夜當晚...
    茶點故事閱讀 44,665評論 2 354

推薦閱讀更多精彩內(nèi)容