正則表達(dá)式(Regular Expressions)是用于匹配字符串中字符組合的模式。在 JavaScript 中,正則表達(dá)式也是對象薛匪。這些模式被用于 RegExp
的 exec
和 test
方法, 以及 String
的 match
匣吊、matchAll
、replace
蹬碧、search
和 split
方法。
創(chuàng)建正則表達(dá)式的方式有兩種:
// 正則表達(dá)式字面量
var re = /ab+c/;
// 使用 RegExp 對象的構(gòu)造函數(shù)
var re = new RegExp("ab+c");
1. 正則表達(dá)式中的特殊字符
-
\
為轉(zhuǎn)義炒刁,通常在\
后面的字符不按原本的意義解釋恩沽。如/b/
匹配字符"b"
,當(dāng) b 前面添加反斜杠/\b/
翔始,轉(zhuǎn)義為匹配一個單詞的邊界罗心。也可以對正則表達(dá)式功能字符的還原里伯,/a*/
將匹配"a"
、"aa"
渤闷、"aaa"
等字符(*
匹配它前面元字符 0 次或多次疾瓮,),加了反斜杠后/a\*/
將只匹配"a*"
飒箭。 -
^
匹配一個輸入或一行的開頭狼电,/^a/
匹配"an A"
字符,而不匹配"An a"
字符弦蹂。 -
$
匹配一個輸入或一行的結(jié)尾肩碟,/a$/
匹配"An a"
字符,而不匹配"an A"
字符凸椿。 -
*
匹配前面元字符 0 次或多次削祈,/ba*/
匹配"b"
、"ba"
脑漫、"baa"
髓抑、"baaa"
等字符。 -
+
匹配前面元字符 1 次或多次优幸,/ba+/
匹配"ba"
吨拍、"baa"
、"baaa"
等字符劈伴。 -
?
匹配前面元元字符 0 次或 1 次密末,/ba?/
匹配"b"
、"ba"
字符跛璧。 -
(x)
匹配x
严里,保存x
在$1...$9
的變量中。 -
x|y
匹配x
或y
追城。 -
{n}
精確匹配 n 次刹碾。 -
{n,}
精確匹配 n 次及以上。 -
{m,n}
精確匹配m ~ n
次座柱。 -
[xyz]
字符集迷帜,匹配這個集合中的任一一個字符(或元字符)。 -
[^xyz]
不匹配這個集合中的任一一個字符色洞。 -
[\b]
匹配一個退格符戏锹。 -
\b
匹配一個單詞的邊界。 -
\B
匹配一個單詞的非邊界火诸。 -
\cX
這里的X
是一個控制符锦针,\cM/
匹配Ctrl-M
。 -
\d
匹配一個數(shù)字字符,/\d/
相當(dāng)于/[0-9]/
奈搜。 -
\D
匹配一個非數(shù)字字符悉盆,/\D/
相當(dāng)于/[^0-9]/
。 -
\n
匹配一個換行符馋吗。 -
\r
匹配一個回車符焕盟。 -
\s
匹配一個空白字符,包括\n
宏粤、\r
脚翘、\f
、\t
商架、\v
等堰怨,相當(dāng)于/[\n\r\f\t\v]/
。 -
\S
匹配一個非空白字符蛇摸,相當(dāng)于/[^\n\r\f\t\v]/
。 -
\t
匹配一個制表符灿巧。 -
\v
匹配一個垂直制表符赶袄。 -
\w
匹配一個可以組成單詞的字符(包括字母、數(shù)字或者下劃線)抠藕。如[\w]
匹配"$5.28"
中的5
饿肺,相當(dāng)于[a-zA-Z0-9]
。 -
\W
匹配一個不可以組成單詞的字符盾似,如[\W]
匹配"$5.28"
中的$
敬辣,相當(dāng)于[^a-zA-Z0-9]
。
2. 直接量字符
如果想在正則表達(dá)式中使用特殊的標(biāo)點(diǎn)符號零院,必須在他們之前加上一個 \
進(jìn)行轉(zhuǎn)義溉跃。
-
\/
表示一個/
直接量。 -
\\
表示一個\
直接量告抄。 -
\.
表示一個.
直接量撰茎。 -
\*
表示一個*
直接量。 -
+
表示一個+
直接量打洼。 -
?
表示一個?
直接量龄糊。 -
\|
表示一個|
直接量。 -
\(
表示一個(
直接量募疮。 -
\)
表示一個)
直接量炫惩。 -
\[
表示一個[
直接量。 -
\]
表示一個]
直接量阿浓。 -
\{
表示一個{
直接量他嚷。 -
\}
表示一個}
直接量。
3. 字符類
將單獨(dú)的直接復(fù)放進(jìn)中括號([...]
)內(nèi)就可以組合成字符類。一個字符類和它所包含的任何一個字符都匹配爸舒。正式表達(dá)式 /[abc]/
和字母 "a"
蟋字、"b"
、"c"
中的任何一個都匹配扭勉,另外還可以定義否定字符類鹊奖,這些類匹配的是除那些包含在中括號之內(nèi)的字符外的所有字符。定義否定字符尖(^
)時涂炎,要將一個 ^
符號作為從左中括號算起的第一個字符忠聚。
由于某些字符類非常常用,所以 JavaScript 的正則表達(dá)式語法包含一些特殊字符和轉(zhuǎn)義序列來表示這些常用的類唱捣。比如 \s
匹配的是空白符(包括空格符两蟀、制表符、換行符等空白符)震缭,\S
匹配的是除空白符之外的任意字符赂毯。
-
[...]
匹配位于括號之內(nèi)的任意字符。 -
[^...]
匹配不在括號內(nèi)的任意字符拣宰。 -
.
匹配除換行符之外的任意字符党涕,相當(dāng)于[^\n]
。 -
\w
匹配任何單字字符巡社,相當(dāng)于[a-zA-Z0-9_]
膛堤。 -
\W
匹配任何非單字字符,相當(dāng)于[^a-zA-Z0-9_]
晌该。 -
\s
匹配任意空白符肥荔,相當(dāng)于/[\n\r\f\t\v]/
。 -
\S
匹配任意非空白符朝群,相當(dāng)于/[^\n\r\f\t\v]/
燕耿。 -
\d
匹配任意數(shù)字,相當(dāng)于[0-9]
潜圃。 -
\D
匹配除數(shù)字之外的任意字符缸棵,相當(dāng)于[^0-9]
。 -
\b
匹配一個退格直接量(特例)谭期。
4. 復(fù)制
用以上的正則表達(dá)式語法堵第,可以把兩位數(shù)描述成 /\d\d/
,把四位數(shù)描述成 /\d\d\d\d/
隧出,但是我們還沒有一種方法可以用來描述具有任意多位數(shù)的數(shù)字或者是一個字符串踏志,這個字符串由三個字符以及跟隨在字母后的一位數(shù)字構(gòu)成。這些復(fù)雜的模式使用的正則表達(dá)式語法指定了改表達(dá)式中每個元素要重復(fù)出現(xiàn)的次數(shù)胀瞪。
指定復(fù)制的字符總是出現(xiàn)在它們所作用的模式后面针余。由于某種復(fù)制類型相對常用饲鄙。所以有一些特殊的字符專門用于表示它們。比如 +
匹配的就是復(fù)制前一模式一次或多次的模式下圆雁。
先看寫例子:
-
/\d{2,4}/
表示匹配 2 ~ 4 個的數(shù)字字符忍级。 -
/\w{3}\d?/
表示匹配三個單字字符和一個任意的數(shù)字。 -
\s+java\s+
表示匹配字符串"java"
伪朽,并且該字符串前后可以有一個或多個空格轴咱。 -
/[^"]*/
表示匹配零個或多個非引號字符。
復(fù)制字符的幾種方式:
-
{m,n}
匹配前一項至少 m 次烈涮,但是不能超過 n 次朴肺。 -
{n,}
匹配前一項 n 次及以上。 -
{n}
匹配前一項恰好 n 次坚洽。 -
?
匹配前一項 0 次或 1 次戈稿,就是說前一項是可選的,相當(dāng)于{0,1}
讶舰。 -
+
匹配前一項 1 次或多次鞍盗,相當(dāng)于{1,}
。 -
*
匹配前一項 0 次或多次跳昼,相當(dāng)于{0,}
橡疼。
5. 選擇、分組庐舟、引用
正則表達(dá)式的語法還包括指定選擇項,對子表達(dá)式分組和引用前一子表達(dá)式的特殊字符住拭。字符 |
用于分隔供選擇的字符挪略,例如:/ab|cd|ef/
匹配的是 "ab"
或者是 "cd"
又或者是 "ef"
字符串。再比如:/\d{3}|[a-z]{4}/
匹配的是要么是一個三位數(shù)字滔岳,要么是四個小寫字母杠娱。
在正則表達(dá)式中,括號((...)
)具有幾種作用:
1?? 它的主要作用是把單獨(dú)的項目分組成子表達(dá)式谱煤,以便可以像處理一個獨(dú)立的單元那種用 *
摊求、+
或 ?
來處理那些項目。例如:/java(script)?/
匹配的是字符串 "java"
刘离,其后的既可以有 "script"
室叉,也可以沒有。再比如硫惕,/(ab|cd)+|ef/
匹配的既可以是字符串 "ef"
茧痕,也可以是字符串 "ab"
或者 "cd"
的一次或多次重復(fù)。
2?? 括號的第二個用途是恼除,在完整的模式中定義子模式踪旷。當(dāng)一個正則表達(dá)式成功地和目標(biāo)字符串相匹配是,可以從目標(biāo)串中抽出和括號中的子模式相匹配的部分。例如令野,假定我們正在檢索的模式是一個或多個字母后面跟隨一位或多位數(shù)組舀患,你們我們可以使用模式 /[a-z]+\d+/
。但是由于假定我們真正關(guān)心的是每個匹配尾部的數(shù)字气破,那么如果我們將模式的數(shù)字部分放在括號中 /[a-z]+(\d+)/
聊浅,我們就可以從所檢索到的任何匹配中抽取數(shù)字了,之后我們會對此進(jìn)行解析的堵幽。
3?? 代括號的另一個用途是狗超,允許我們在同一正則表達(dá)式的后面引用前面的子表達(dá)式。這是通過在字符串 \
后加一位或多位數(shù)字來實(shí)現(xiàn)的朴下。數(shù)字指的是代括號的子表達(dá)式在正則表達(dá)式中的位置努咐。例如:\1
引用的的是第一個代括號的子表達(dá)式,\3
引用的是第三個代括號的子表達(dá)式殴胧。注意渗稍,由于子表達(dá)式可以嵌套在其他子表達(dá)式中,所以它的位置是被計數(shù)的左括號的位置团滥。
例如竿屹,在下面的正則表達(dá)式被指定為 \2
:/([Jj]ava[Ss]cript)\sis\s(fun\w*)/
,對正則表達(dá)式中前一子表達(dá)式的引用所指定的并不是那個子表達(dá)式灸姊,而是與那個模式相匹配的文本拱燃。這樣,引用就不只是幫助你輸入正則表達(dá)式的重復(fù)部分的快捷方式了力惯,它還實(shí)施了一條規(guī)約碗誉,那就是一個字符串各個分離的部分包含的是完全相同的字符。例如:/['"][^'"]['"]/
匹配的就是位于單引號或者雙引號之內(nèi)的所有字符父晶。但是它要求開始和結(jié)束的引號匹配哮缺。(例如兩個都是雙引號或者都是但引號)
如果要求開始和結(jié)束的引號匹配,我們可以使用如下的引用:/(['"])[^'"]*\1/
甲喝,\1
匹配的是第一個代括號的子表達(dá)式所匹配的模式尝苇。在這個例子中,它實(shí)施了一種規(guī)約埠胖,那就是開始的引號必須和結(jié)束的引號相匹配糠溜。注意,如果反斜杠后跟隨的數(shù)字比代括號的子表達(dá)式數(shù)多押袍,那么它就會被解析為一個十進(jìn)制的轉(zhuǎn)義序列诵冒,而不是一個引用。你可以堅持使用完整的三個字符來表示轉(zhuǎn)義序列谊惭,這樣就可以避免混淆了汽馋。例如 \044
侮东,而不是 \44
。
下面是正則表達(dá)式的選擇豹芯、分組和引用字符:
-
|
選擇:匹配的要么是該符號左邊的子表達(dá)式悄雅,要么是它右邊的子表達(dá)式。 -
(...)
分組:將幾個項目分為一個單元铁蹈,這個單元可由*
宽闲、+
、?
和|
等符號使用握牧,而且還可以記住和這個組匹配的字符以供此后引用使用\n
和第n
個(注意這里的n
是指數(shù)字)分組所匹配的字符相匹配容诬。分組是括號中的子表達(dá)式。(可能是嵌套的)分組號是從左到右計數(shù)的左括號數(shù)沿腰。
6. 通過標(biāo)志進(jìn)行高級搜索
正則表達(dá)式有六個可選參數(shù)(flags
)允許全局和不分大小寫搜索等览徒。這些參數(shù)既可以單獨(dú)使用,也能以任意順序一起使用颂龙,并且被包含在正則表達(dá)式實(shí)例中习蓬。
-
g
全局搜索 -
i
不區(qū)分大小寫搜索 -
m
多行搜索。 -
s
允許.
匹配換行符措嵌。 -
u
使用 unicode 碼的模式進(jìn)行匹配躲叼。 -
y
執(zhí)行“粘性(sticky)”搜索,匹配從目標(biāo)字符串的當(dāng)前位置開始。
// 正則表達(dá)式字面量
var re = /pattern/flags;
// RegExp 構(gòu)造函數(shù)
var re = new RegExp("pattern", "flags");
7. 動態(tài)創(chuàng)建正則表達(dá)式
從用戶輸入等來源中動態(tài)地產(chǎn)生企巢,就需要使用構(gòu)造函數(shù)來創(chuàng)建正則表達(dá)式枫慷。
// 假設(shè)需求是生成一個正則表達(dá)式:/temp/
// 此時我們手上有一個字符串 "temp"
var str = 'temp';
// 這種方式是不對的,得到的只是一個 "/temp/" 字符串浪规。
var re = '/' + str + '/';
// 應(yīng)該是這樣流礁,才是正則表達(dá)式
var re = new RegExp(str);
未完待續(xù)...