來(lái)自SegmentFault的:wupengyu
為什么要使用正則表達(dá)式
正則表達(dá)式通過(guò)由普通字符和特殊字符組成的文字模板完成對(duì)字符串的校驗(yàn),搜索掏熬,替換。在javascript中類似這樣
/^1\d{10}$/
上面的這個(gè)簡(jiǎn)單的正則用來(lái)匹配手機(jī)號(hào)至于說(shuō)正則表達(dá)式到底有什么意義秒梅,借由《精通正則表達(dá)式》里面的一句話來(lái)概括好了旗芬。
? “如果羅列計(jì)算機(jī)軟件領(lǐng)域的偉大發(fā)明,我相信絕對(duì)不會(huì)超過(guò)二十項(xiàng)捆蜀,在這個(gè)名單當(dāng)中疮丛,當(dāng)然應(yīng)該包括分組交換網(wǎng)絡(luò),Web辆它,Lisp誊薄,哈希算法,UNIX锰茉,編譯技術(shù)呢蔫,關(guān)系模型,面向?qū)ο箪琗ML這些大名鼎鼎的家伙片吊,而正則表達(dá)式也絕對(duì)不應(yīng)該被漏掉绽昏。?對(duì)很多實(shí)際工作而言,正則表達(dá)式簡(jiǎn)直是靈丹妙藥俏脊,能夠成百倍的提高開發(fā)效率和程序質(zhì)量全谤。”
正則表達(dá)式的生成
在javascript中生成正則表達(dá)式的方式有兩種
1.調(diào)用RegExp對(duì)象的構(gòu)造函數(shù)
var reg = new RegExp('^[a-z]+[0-9]$', 'gi')
其中第一個(gè)參數(shù)是匹配模式爷贫,第二個(gè)參數(shù)是可選參數(shù)(g, i, m),分別用于指定全局匹配认然、區(qū)分大小寫的匹配和多行匹配。這種方式會(huì)在正則表達(dá)式運(yùn)行時(shí)編譯(runtime compilation)漫萄。如果你知道正則表達(dá)式模式將會(huì)改變季眷,或者你事先不知道什么模式,而是從另一個(gè)來(lái)源獲取卷胯,如用戶輸入子刮,這些情況都可以使用構(gòu)造函數(shù)。
2.使用正則表達(dá)式字面值窑睁,將匹配模式封閉在兩個(gè)斜杠中
var reg = /^[a-z]+[0-9]$/gi
當(dāng)表達(dá)式被賦值時(shí)挺峡,字面量形式提供正則表達(dá)式的編譯(compilation),當(dāng)正則表達(dá)式保持為常量時(shí)一般使用字面量方式担钮。例如當(dāng)你在循環(huán)中使用字面量構(gòu)造一個(gè)正則表達(dá)式時(shí)橱赠,正則表達(dá)式不會(huì)在每一次迭代中都被重新編譯(recompiled)。
正則表達(dá)式的組成
正則表達(dá)式的文字模板是有很多不同類型的字符組成的箫津,包括:元字符狭姨,轉(zhuǎn)義字符,限定符苏遥,字符組饼拍,或結(jié)構(gòu),括號(hào)分組
元字符
字符 | 含義 |
---|---|
. | 匹配除了換行符(n)以外的所有字符 |
w | 匹配字母田炭,數(shù)字师抄,或者漢字 |
W | 匹配除了字母,數(shù)字教硫,漢字以外的其他字符 |
d | 匹配數(shù)字 |
D | 匹配除了數(shù)字以外的其他字符 |
s | 匹配任意的空白符(f, n, r, t, v) |
S | 匹配空白符以外的任意字符 |
b | 匹配單詞的開始或者結(jié)束 |
B | 匹配單詞的非開始或者結(jié)束 |
^ | 匹配行首 |
$ | 匹配行尾 |
轉(zhuǎn)義字符
* + ? | { [ ( ) ] }^ $ . # 和 空白 這些字符都是需要轉(zhuǎn)義的叨吮。例如我們要匹配{。
\{
限定符
字符 | 含義 |
---|---|
* | 匹配零次至多次 |
+ | 匹配一次至多次 |
瞬矩? | 匹配零次或一次 |
{2,} | 至少匹配兩次 |
{10} | 匹配10次 |
{{2, 8}} | 至少匹配兩次之多匹配八次 |
字符組[]
中括號(hào)字符組用來(lái)匹配括號(hào)內(nèi)的字符之一
'fasfagxfasdfyfasfz'.split(/[xyz]/) //["fasfag", "fasdf", "fasf", ""]
還有一種排除性字符組
'xaxbycz'.split(/[^xyz]/) //["x", "x", "y", "z"]
或結(jié)構(gòu) |
例如c|d匹配或者d
/c|d/.test('af') // false
/c|d/.test('ad') // true
括號(hào)分組
(cd){1,} 可以匹配cdcd..等, 其中cd便是一個(gè)分組茶鉴。
/(cd){1,}$/.test('cdcd') //true
貪婪模式和非貪婪模式
默認(rèn)情況下,所有的限定詞都是貪婪模式景用,表示盡可能多的去捕獲字符涵叮。而在限定詞后增加“?”,則是非貪婪模式,表示盡可能少的去捕獲字符围肥。
'ccccccd'.match(/c+/) //["ccccc"]剿干, 貪婪模式, 捕獲所有
'ccccccd'.match(/c+蜂怎?/) //["c"]穆刻, 非貪婪模式, 只捕獲到第一個(gè)
捕獲分組
在實(shí)際應(yīng)用中我們很有可能需要獲取到匹配的字符串,例如我們要將字符串"萬(wàn)里碧空飄著朵朵白云"替換成"萬(wàn)里碧空沒(méi)有一朵白云"
"萬(wàn)里碧空飄著朵朵白云".replace(/(萬(wàn)里碧空)飄著朵朵白云/, '$1沒(méi)有一朵白云')
捕獲性分組會(huì)創(chuàng)建反向引用杠步,js中可以通過(guò) $+number 或者 "反斜杠"+number" 表示法進(jìn)行引用氢伟。
注意:
反斜杠+number這種引用可以在正則表達(dá)式中使用,可用于匹配不同位置的相同子串幽歼,例如:
'www.bai.bai.com'.replace(/([a-z]+)\.\1/, '$1') // www.bai.com
非捕獲性分組
非捕獲性分組朵锣,通常由一對(duì)括號(hào)加上”?:”加上子表達(dá)式組成,非捕獲性分組不會(huì)創(chuàng)建反向引用甸私,就好像沒(méi)有括號(hào)一樣诚些。捕獲性分組和無(wú)捕獲性分組在搜索效率方面也沒(méi)什么不同,沒(méi)有哪一個(gè)比另一個(gè)更快皇型。
/^(?:\d+)/
正則表達(dá)式的方法
test
檢索字符串中的指定子串诬烹,返回布爾值
/^\d[a-zA-Z]{3}$/.test('1aac') // true
exec
返回一個(gè)數(shù)組,數(shù)組中的第一個(gè)條目是第一個(gè)匹配
/^\d[a-zA-Z]{3}$/.exec('1aac') // ["1aac"]
String可以使用正則表達(dá)式的方法
search
返回子串的開始位置
'a12b2334c34'.search(/\d{4}/) // 4
match
返回匹配到的子串
'a12b2334c34'.match(/\d{4}/) // ["2334"]
replace
替換匹配到的子串
'a12b2334c34'.replace(/\d{4}/, 'cccc') // "a12bccccc34"
split
將字符串分割成數(shù)組
'a12b2334c34'.split(/\d{4}/) // ["a12b", "c34"]
斷言
正向先行斷言 (?=exp)
代表字符串中的一個(gè)位置弃鸦,緊接該位置之后的字符序列能夠匹配 exp
/f(?=234)/.test('123abcf234acd') //true
負(fù)向先行斷言(?!exp)
代表字符串中的一個(gè)位置绞吁,緊接該位置之后的字符序列不能匹配 exp
/f(?!234)/.test('123abcf234acd') //false