
前言
接著例子詳解正則表達(dá)式(一)往下講。
1.特殊字符:. (小數(shù)點(diǎn))
|字符|匹配規(guī)則|
|:--:|--|
|.|(小數(shù)點(diǎn))匹配除換行符之外的任何單個(gè)字符。例如,/.n/將會(huì)匹配 "nay, an apple is on the tree" 中的 'an' 和 'on',但是不會(huì)匹配 'nay'。|
直接上例子:
var str="nay, an apple is on the tree";
// g標(biāo)志表示全局搜索
var pattern = /.n/g; // 匹配字符串中的一個(gè)2字節(jié)子串,由一個(gè)非換行符字符+n
console.log(str.replace(pattern, 'N')); // nay, N apple is N the tree
2.特殊字符:(x)
|字符|匹配規(guī)則|
|:--:|--|
|(x)|匹配 'x' 并且記住匹配項(xiàng),就像下面的例子展示的那樣。括號(hào)被稱為 捕獲括號(hào)。模式 /(foo) (bar) \1 \2/ 中的 '(foo)' 和 '(bar)' 匹配并記住字符串 "foo bar foo bar" 中前兩個(gè)單詞。模式中的 \1 和 \2 匹配字符串的后兩個(gè)單詞。注意 \1、\2、\n 是用在正則表達(dá)式的匹配環(huán)節(jié)。在正則表達(dá)式的替換環(huán)節(jié),則要使用像 $1、$2、$n 這樣的語法,例如,'bar foo'.replace( /(...) (...)/, '$2 $1' )。|
補(bǔ)充說明:正如上面的說的,() 可以記住第一次匹配到的字串,并依次將記住的字串放在一個(gè)列表里面,然后用 \x (x = 0,1,2,3……) 可以訪問列表里面的子串,用在正則表達(dá)式里面,比如上面表格中的例子/(foo) (bar) \1 \2/中的(foo), 他第一次匹配到的子串一定是 "foo" (假定父字符串中有foo),那么foo就會(huì)被記錄在一個(gè)列表,然后因?yàn)閒oo是第一個(gè)被匹配的,所以用\1可以訪問到它,所以其實(shí)上面的正則表達(dá)式等價(jià)于/foo bar foo bar /,然后肯定會(huì)疑惑,為什么不直接這樣寫?看下面例子:
var str1 = "foo foo",
str2 = "fooo fooooo",
str3 = "foo fo";
var pattern = /(fo*) \1/;
console.log(str1.replace(pattern, "FO*")); // 輸出FO*
console.log(str2.replace(pattern, "FO*")); // FO*oo
console.log(str3.replace(pattern, "FO*")); // foo fo
先看上面str1的輸出,是FO*,你會(huì)發(fā)現(xiàn) foo foo 全部被 FO* 替換。這不就相當(dāng)于父串被 /fo* foo/匹配了嗎?換言之 \1 等價(jià)于 foo,然后 fo*第一次匹配的正是 foo foo中的 foo 。
再看str2,輸出的是 FO*oo,被替換掉的部分是:fooo fooo。那么上面代碼中的pattern就相當(dāng)于 /fo* fooo/。
再看str3,是原樣輸出,為什么呢?pattern 中 fo* 第一次匹配到的字串是 foo,那么pattern就等價(jià)于 /fo* foo/,顯然父串中并沒有匹配項(xiàng),因此原樣輸出。
小結(jié):帶()特殊字符的正則表達(dá)式,會(huì)對(duì)父串匹配兩次。第一次匹配是為了將每個(gè)記錄放進(jìn)”列表“中,然后解析當(dāng)前正則表達(dá)式為"真"正則表達(dá)式(解析當(dāng)前正則表達(dá)式中的\x x=123..n),第二次才開始真正的匹配。
3.特殊字符:(?:x)
|字符|匹配規(guī)則|
|:--:|--|
|(?:x)|匹配 'x' 但是不記住匹配項(xiàng)。這種叫作非捕獲括號(hào),使得你能夠定義為與正則表達(dá)式運(yùn)算符一起使用的子表達(dá)式。來看示例表達(dá)式 /(?:foo){1,2}/。如果表達(dá)式是 /foo{1,2}/,{1,2}將只對(duì) ‘foo’ 的最后一個(gè)字符 ’o‘ 生效。如果使用非捕獲括號(hào),則{1,2}會(huì)匹配整個(gè) ‘foo’ 單詞。|
補(bǔ)充說明:該字符和第二個(gè)特殊字符的作用有點(diǎn)類似,但是不同的是:該字符沒有”記住“的能力。他存在意義正如表格中的介紹:
表達(dá)式是 /foo{1,2}/,{1,2}將只對(duì) ‘foo’ 的最后一個(gè)字符 ’o‘ 生效。
ps:{1, 2}的意思是:至少前面的字符至少出現(xiàn)1~2次,比如?可以寫成:{0, 1}
var str1 = str2 = "many foofoofoo";
var pattern1 = /(?:foo)+/, // 匹配父串中的 foo...foo或foo
pattern2 = /foo+/; // 匹配父串中的foo...o或foo
console.log(str1.replace(pattern1, "FOO")); // 輸出many FOO
console.log(str2.replace(pattern2, "FOO")); // 輸出many FOOfoofoo
說道這里,我補(bǔ)充一點(diǎn)比較重要的知識(shí)點(diǎn)(不論你有沒有明白到這一點(diǎn)):正則表達(dá)式在匹配父串的時(shí)候,是逐個(gè)字符去匹配,以每個(gè)字符作為一個(gè)單位
小結(jié):(?:x) 是將 x 作為一個(gè)單位去匹配父串
- 各位觀眾老爺,今天就到這里,且聽下回分解。
附錄
| 字符 | 作用 |
|---|---|
| g | 全局搜索。 |
| 字符 | 匹配規(guī)則 |
|---|---|
| {n,m} | n 和 m 都是正整數(shù)。匹配前面的字符至少n次,最多m次。如果 n 或者 m 的值是0, 這個(gè)值被忽略。例如,/a{1, 3}/ 并不匹配“cndy”中得任意字符,匹配“candy”中得a,匹配“caandy”中得前兩個(gè)a,也匹配“caaaaaaandy”中得前三個(gè)a。注意,當(dāng)匹配”caaaaaaandy“時(shí),匹配的值是“aaa”,即使原始的字符串中有更多的a。 |