ECMAScript通過RegExp類型來支持正則表達式,常見的正則表達式為:var expression = /pattern / flags;其中的模式(pattern)部分可以使任何簡單或復雜的正則表達式,可以包括字符類、限定符、分組、向前查找以及反向引用。每個正則表達式都可帶有一個或者多個標志(flags),用以標明正則表達式的行為。正則表達式的匹配模式支持下列3個標志:
- g:表示全局(global)模式,即模式將被應用於所有的字符串,而非在發現第一個匹配項時立即停止。
- i:表示不區分大小寫(case-insensitive)模式,即在確定匹配項時忽略模式與字符串的大小寫。
m:表示多行(multiline)模式,即在到達一行文本末尾時還會繼續查找下一行中是否存在與模式匹配的項。
var pattern1 = /at/g; //匹配字符串中所有的"at"的實例
var pattern2 = /[bc]at/i; //匹配第一個'bat'或'cat',不區分大小寫
var pattern3 = /.at/gi //匹配所有以'at'結尾的3個字符的組合,不區分大小寫
var pattern4 = /\.at/gi //匹配所有的'.at',不區分大小寫
上面的例子中都是以字面量形式來定義的正則表達式,除此之外,我們還可以使用RegExp構造函數來定義正則表達式,這種方式需要兩個參數:匹配的字符串模式和可選的標志字符串(兩個參數都必須是字符串,不能把正則表達式字面量傳遞給RegExp構造函數)。var pattern11 = new RegExp("[bc]at","i");
正則表達式模式中使用的所有元字符都必須轉義,正則表達式中的元字符包括:( | ( \ ^ $ |] ? * + .]} 由於RegExp構造函數的模式參數是字符串,所有再某些情況下需要對字符進行雙重轉義,所有元字符都必須雙重轉義,那些已經轉義過的字符也是如此。
RegExp實例屬性
在上面我們知道了,每個正則表達式都可帶有一個或者多個標志(flags),用以標明正則表達式的行為。但並不是所有的正則都帶有標志,因此我們可以通過相應的實例屬性來判斷正則表達式的相關信息。
- global:布爾值,表示是否設置了g標志。
- ignoreCase:布爾值,表示是否設置了i標志。
- lastIndex:整數,表示開始搜索下一個匹配項的字符位置,從0算起。
- multiline:布爾值,表示是否設置了m標志
- source:正則表達式的字符串表示,按照字面量形式而非傳入構造函數中的字符串模式返回。
var a1 = /\[bc\]at/i;
console.log(a1.global); //false
console.log(a1.ignoreCase); //true
console.log(a1.lastIndex); //0
console.log(a1.multiline); //false
console.log(a1.source); //\[bc\]at
var a2 = new RegExp("\\[bc\\]at","i");
console.log(a2.global); //false
console.log(a2.ignoreCase); //true
console.log(a2.lastIndex); //0
console.log(a2.multiline); //false
console.log(a2.source); //\[bc\]at
exec()
exec()方法是專門為捕獲組而設計,接收應用模式的字符串作為參數,返回包含第一個匹配項信息的數組,或者在沒有匹配項的情況下返回null,返回的雖然是數組,但包含兩個額外的屬性:index和input,其中,index表示匹配項在字符串中的位置,input表示應用正則表達式的字符串,而在數組中,第一項是與整個模式匹配的字符串,其他項是與模式中的捕獲組匹配的字符串。
var text = "mom and dad and baby";
var b1 = /mom( and dad( and baby)?)?/gi;
var b2 = b1.exec(text);
console.log(b2.index); //0
console.log(b2.input); //mom and dad and baby
console.log(b2[0]); //mom and dad and baby
console.log(b2[1]); //and dad and baby
console.log(b2[2]); //and baby
上面這個例子中的模式包含兩個捕獲組,最內部的捕獲組匹配"and baby",而包含它的捕獲組匹配"and baby"或者"and dad and baby",當把字符串傳入exec()方法中之后,發現了一個匹配項,因為整個字符串本身與模式匹配,所有返回的數組matchs的index屬性值為0,數組中的第一項是匹配的整個字符串,第二項包含與第一個捕獲組匹配的內容,第三項包含與第二個捕獲組匹配的內容。
對於exec方法而言,即使在模式中設置了全局標志(g),它每次也只返回一個匹配項。在不設置全局標志的情況,在同一個字符串上多次調用exec()將始終返回第一個匹配項的信息,而在設置了全局標志的情況下,每次調用exec()則都會在字符串中繼續查找新的匹配項。
var text2 = 'cat,bat,sat,fat';
var c1 = /.at/;
var c2 = c1.exec(text2);
console.log(c2.index); //0
console.log(c2[0]); //cat
console.log(c1.lastIndex); //0
var c3 = /.at/g;
var c4 = c3.exec(text2);
console.log(c4.index); //0
console.log(c4[0]); //cat
console.log(c3.lastIndex); //3
test()
test()方法接收一個字符串參數,在模式與該參數匹配的情況下返回true;否則返回false,常被用在if語句中。
var text3 = '000-00-0000';
var c5 = /\d{3}-\d{2}-\d{4}/;
if(c5.test(text3)){
console.log('匹配成功!') //匹配成功!
}
構造函數屬性
在RegExp構造函數中存在一些屬性,這些屬性適用於作用域中的所有正則表達式,並基於所執行的最近一次正則表達式操作而變化,關於這些屬性的獨特之處在於,可以通過兩種方式訪問:長屬性名和短屬性名(opera不支持短屬性名)(opear不支持input、lastMatch、lastParen和multiline,IE不支持multiline)。
var text4 = "this has been a short summer";
var c6 = /(.)hort/g;
if(c6.test(text4)){
console.log(RegExp.input); //this has been a short summer
console.log(RegExp.leftContext); //this has been a
console.log(RegExp.rightContext); //summer
console.log(RegExp.lastMatch); //short
console.log(RegExp.lastParen); //s
console.log(RegExp.multiline); //undefined
}
if(c6.test(text4)){
console.log(RegExp.$_); //this has been a short summer
console.log(RegExp["$`"]); //this has been a
console.log(RegExp["$|"]); //summer
console.log(RegExp["$&"]); //short
console.log(RegExp["$+"]); //s
console.log(RegExp["$*"]); //undefined
}