JavaScript - 正則表達(dá)式

RegExp 類型是 ECMAScript 支持正則表達(dá)式的一個接口揍异,提供了最基本的和一些高級的正則表達(dá)式功能馅而。

函數(shù)實際上是 Function 類型的實例,因此函數(shù)也是對象;而這一點整是 JavaScript 最有特色的地方宙地。由于函數(shù)對象,所以函數(shù)也擁有方法逆皮,可以用來爭搶其行為宅粥。

因為有了基本包裝類型,所以 JavaScript 中的基本類型值可以被當(dāng)做對象來訪問电谣,三種基本包裝類型分別是:Boolean秽梅、Number和String。

  • 每個包裝類型都映射到同名的基本類型剿牺。
  • 在讀取模式下訪問基本類型值時企垦,就會創(chuàng)建對應(yīng)的基本包裝類型的一個對象,從而方便了數(shù)據(jù)操作晒来。
  • 操作基本類型值的語句一經(jīng)執(zhí)行完畢钞诡,就會立即銷毀新創(chuàng)建的包裝對象。

在所有代碼執(zhí)行之前湃崩,作用域中就已經(jīng)存在兩個內(nèi)置對象:Global 和 Math 荧降。在大多數(shù) ECMAScript 實現(xiàn)中都不能直接訪問 Global 對象;不過攒读,Web 瀏覽器實現(xiàn)了承擔(dān)該角色的 window 對象朵诫。全局變量和函數(shù)都是 Global 對象的屬性。Math 對象提供了很多屬性和方法薄扁,用于輔助完成復(fù)雜的數(shù)學(xué)計算任務(wù)剪返。

創(chuàng)建正則表達(dá)式

var expression = / pattern / flags ;
var expression1 = new RegExp('pattern', flags);

使用類似Perl的語法废累,可以創(chuàng)建一個正則表達(dá)式邑滨。

其中的模式(pattern)部分可以是任何簡單或復(fù)雜的正則表達(dá)式驼修,可以包含字符類乙各、限定符、分組幢竹、向前查找以及反向引用耳峦。

  • g:表示全局(global)模式焕毫,即模式將被應(yīng)用于所有字符串蹲坷,而非在發(fā)現(xiàn)第一個匹配項時立即停止;
  • i:表示不區(qū)分大小寫(case-insensitive)模式邑飒,即在確定匹配項時忽略模式與字符串的大小寫循签;
  • m:表示多行(multiline)模式,即在到達(dá)一行文本末尾時還會繼續(xù)查找下一行中是否存在于模式匹配的項县匠;

與其他語言中的正則表達(dá)式類似,模式中使用的所有元字符都必須轉(zhuǎn)義兰粉。

/*
  正則表達(dá)式包括:

  ( [ { / ^ $ | ? * + . } ] )

  這些元字符在正則表達(dá)式中都有一或多種特殊用途顶瞳,因此如果想要匹配字符串中包含的這些字符,就必須對它們進(jìn)行轉(zhuǎn)義
*/


// 匹配字符串中所有 'at' 的實例
var pattern1 = /at/g;


// 匹配第一個'bat' 或 'cat', 不區(qū)分大小寫
var pattern2 = /[bc]at/i;

// 匹配第一個'[bc]at', 不區(qū)分大小寫
var pattern2 = /\[bc\]at/i;


// 匹配所有以 ' at' 結(jié)果的3個字符的組合抡柿,不區(qū)分大小寫
var pattern3 = /. at/gi;

// 匹配所有以 '.at'等恐,不區(qū)分大小寫
var pattern3 = /\. at/gi;
字面量模式 等價的字符串
/[bc]at/ "\\[bc\\]at"
/.at/ "\\.at"
/name/age/ "name\\/age"
/\d.\d{1, 2}/ "\\d.\\d{1, 2}"
/\w\hello\123/ "\\w\\\\hello\\\\123"

字符串 \ 在字符串中通常被轉(zhuǎn)義為 \\, 而在正則表達(dá)式字符串中就會變成 \\\\

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");
}

test() 方法用來匹配傳入的字符串是否符合正則表達(dá)式战惊。

ECMAscript 5 之前 使用字面量不是創(chuàng)建一個新的正則表達(dá)式實例,有點像單例模式刁绒,會導(dǎo)致循環(huán)調(diào)用test時失敗的情況烤黍。

ECMAScript 5 明確規(guī)定,使用正則表達(dá)式字面量必須像直接調(diào)用RegExp構(gòu)造函數(shù)一樣,每次都創(chuàng)建新的RegExp示例媳叨。IE9、Fiefox 4+、和Chrome都據(jù)此做出了修改伍纫。

RegExp 實例屬性

RegExp 對象的主要方法是 exec(), 該方法是專門為捕獲組而設(shè)計的舞虱。 exec() 接受一個參數(shù),即要應(yīng)用模式的字符串母市,然后返回包含第一個匹配項信息的數(shù)組返帕;或者在沒有匹配項的情況下返回 null溉旋。

返回的數(shù)組雖然是Array的實例观腊,但包含兩個額外的屬性:index 和 input。

其中 index 表示匹配項在字符串中的位置呀枢,而 input 表示應(yīng)用正則表達(dá)式的字符串胚股。

在數(shù)組中,第一項是與整個模式匹配的字符串裙秋,其他項是與模式中的捕獲組匹配的字符串(如果模式中沒有捕獲組琅拌,則該數(shù)組只包含一項)雁乡。

Exec

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",而包含它的捕獲組匹配 "ant dad" 或者 "and dad and baby"蝗茁。

當(dāng)把字符串傳入 exec() 方法中之后枷恕,發(fā)現(xiàn)了一個匹配項党晋。

因為整個字符串本身與模式匹配,所以返回的數(shù)組 matchs 的 index 屬性值為 0。

數(shù)組中的第一項是匹配的整個字符串未玻,第二項包含與第一個捕獲組匹配的內(nèi)容漏益,第三項包含與第二個捕獲組匹配的內(nèi)容。

對于 exec() 方法而言深胳,即使在模式中設(shè)置了全局標(biāo)志(g),它每次也只會返回一個匹配項铜犬。

在不設(shè)置全局標(biāo)志的情況下舞终,在同一個字符串上多次調(diào)用 exec() 將始終返回第一個匹配項的信息。

而在設(shè)置全局標(biāo)志的情況下癣猾,每次調(diào)用 exec() 則都會在字符串中繼續(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

上面例子中 pattern1 不是全局模式,因此每次調(diào)用 exec() 返回的都是第一個匹配項 ("cat")纷宇。

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

上面例子中 pattern2 是全局模式夸盟,因此每次調(diào)用 exec() 都會返回字符串中的下一個匹配項,直至搜索到字符串末尾為止像捶。

注意 lastIndex 的變化上陕,在全局匹配模式下,lastIndex的值在每次調(diào)用 exec() 后都會增加拓春,而在非全局模式下則始終保持不變释簿。

test

接受一個字符串參數(shù),在模式與該參數(shù)匹配的情況下返回 true硼莽,否則返回 false庶溶。

在指向知道目標(biāo)字符串與某個模式是否匹配,但不需要指定其文本內(nèi)容的情況下懂鸵,使用這個方法非常方便偏螺。

因此,test() 方法經(jīng)常被用在id語句中匆光。

var text = "000-00-0000";
var pattern = /\d{3}-\d{2}-\d{4}/;

if (pattern.test(text)) {
    alert("匹配成功")
}

RegExp 構(gòu)造函數(shù)屬性

RegExp 構(gòu)造函數(shù)包含一些屬性(這些屬性在其他語言中被看成是靜態(tài)屬性)套像。

這些屬性適用于作用域中的所有正則表達(dá)式,并且基于所有執(zhí)行的最近一次正則表達(dá)式操作而變化终息。

關(guān)于這些屬性的另一個獨(dú)特之處凉夯,就是可以通過連各種方式訪問它們。

這些屬性分別有一個長屬性名和一個短屬性名(Opera是例外采幌,它不支持短屬性名)劲够。

長屬性名 短屬性名 說明
input $_ 最近一次要匹配的字符串(Opera未實現(xiàn))
lastMatch $& 最近一次的匹配項(Opera未實現(xiàn))
lastParen $+ 最近一次的匹配的捕獲組(Opera未實現(xiàn))
lastContext $ input 字符串中 lastMatch 之前的文本
multiline $* 布爾值,表示是否所有表達(dá)式都使用多行模式休傍。(IE和Opera未實現(xiàn))
rightContext $' Input 字符串中 lastMatch 之后的文本

使用這些屬性可以從 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); // undefined
}
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['$*']); // undefined
}
  • input 屬性返回了原始字符串。
  • leftContext 屬性返回了單詞 short 之前的字符串。
  • rightContext 屬性返回了單詞 short 之后的字符串人柿。
  • lastMatch 屬性返回最近一次與整個正則表達(dá)式匹配的字符串柴墩。
  • lastParen 屬性返回最近一次匹配的捕獲數(shù)組,即例子中的 s凫岖。

模式的局限

  • 不匹配字符串開始和結(jié)尾的 \A 和 \Z 錨

    但支持以插入符號 (^) 和美元符號 ($) 來匹配字符串的開始和結(jié)尾江咳。

  • 不支持向后查找(lookbehind)

    但完全支持向前查找(lookahead)。

  • 不支持原子組(atomic grouping)

  • 不支持Unicode(單個字符除外哥放,如 \uFFFF)

  • 不支持命名的捕獲組

    但支持編號的捕獲組

  • 不支持 s(single, 單行)x(free-spacing歼指,無間隔) 匹配模式

  • 不支持條件匹配

  • 不支持正則表達(dá)式注釋

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市甥雕,隨后出現(xiàn)的幾起案子踩身,更是在濱河造成了極大的恐慌,老刑警劉巖社露,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挟阻,死亡現(xiàn)場離奇詭異,居然都是意外死亡峭弟,警方通過查閱死者的電腦和手機(jī)附鸽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瞒瘸,“玉大人拒炎,你說我怎么就攤上這事“の瘢” “怎么了击你?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長谎柄。 經(jīng)常有香客問我丁侄,道長,這世上最難降的妖魔是什么朝巫? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任鸿摇,我火速辦了婚禮,結(jié)果婚禮上劈猿,老公的妹妹穿的比我還像新娘拙吉。我一直安慰自己,他們只是感情好揪荣,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布筷黔。 她就那樣靜靜地躺著,像睡著了一般仗颈。 火紅的嫁衣襯著肌膚如雪佛舱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機(jī)與錄音请祖,去河邊找鬼订歪。 笑死,一個胖子當(dāng)著我的面吹牛肆捕,可吹牛的內(nèi)容都是我干的刷晋。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼慎陵,長吁一口氣:“原來是場噩夢啊……” “哼眼虱!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起荆姆,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎映凳,沒想到半個月后胆筒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡诈豌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年仆救,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矫渔。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡彤蔽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出庙洼,到底是詐尸還是另有隱情顿痪,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布油够,位于F島的核電站蚁袭,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏石咬。R本人自食惡果不足惜揩悄,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鬼悠。 院中可真熱鬧删性,春花似錦、人聲如沸焕窝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽它掂。三九已至汗侵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晰韵。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工发乔, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人雪猪。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓栏尚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親只恨。 傳聞我的和親對象是個殘疾皇子译仗,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

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