一、重要點整理
- ^ 爲匹配輸入字符串的開始位置。
-
[0-9]+匹配多個數字, [0-9] 匹配單個數字,+ 匹配一個或者多個。[^…] 排除型字符組。
-
abc$匹配字母 abc 並以 abc 結尾,$ 爲匹配輸入字符串的結束位置。
-
正則表達式由兩種字符構成。一種是在正則表達式中具體特殊意義的“元字符”,另一種是普通的“文本字符”。元字符可以是一個字符,如“^”,也可以是一個字符序列,如“\w”。
-
空白字符:[ \r\n\f\t\v]解釋:\f 匹配換頁字符。 \n 匹配換行字符。 \r 匹配回車符字符。 \t 匹配製表字符。 \v 匹配垂直製表符。
-
\n和\r區別:回車 \r 本義是光標重新回到本行開頭,r的英文return,控制字符可以寫成CR,即Carriage Return
換行 \n 本義是光標往下一行(不一定到下一行行首),n的英文newline,控制字符可以寫成LF,即Line -
[.?!]:匹配標點符號.?!
-
分組:
二、正則表達式基礎
2.1 正則表達式構成
正則表達式由兩種字符構成。一種是在正則表達式中具體特殊意義的“元字符”,另一種是普通的“文本字符”。
元字符可以是一個字符,如“^”,也可以是一個字符序列,如“\w”。
2.2 元字符(Meta Character)
2.2.1 […] 字符組(Character Classes)
字符組可以匹配[ ]中包含的任意一個字符。雖然可以是任意一個,但只能是一個。
字符組支持由連字符“-”來表示一個範圍。當“-”前後構成範圍時,要求前面字符的碼位小於後面字符的碼位。
[^…] 排除型字符組。排除型字符組表示任意一個未列出的字符,同樣只能是一個。排除型字符組同樣支持由連字符“-”來表示一個範圍。
表達式 |
說明 |
[abc] |
表示“a”或“b”或“c” |
[0-9] |
表示0~9中任意一個數字,等價於[0123456789] |
[\u4e00-\u9fa5] |
表示任意一個漢字 |
[^a1<] |
表示除“a”、“1”、“<”外的其它任意一個字符 |
[^a-z] |
表示除小寫字母外的任意一個字符 |
舉例:
“[0-9][0-9]”在匹配“Windows 2003”時,匹配成功,匹配的結果爲“20”。
“[^inW]”在匹配“Windows 2003”時,匹配成功,匹配的結果爲“d”。
2.2.2 常見字符範圍縮寫
對於一些常用的字符範圍,如數字等,由於非常常用,即使使用[0-9]這樣的字符組仍顯得麻煩,所以定義了一些元字符,來表示常見的字符範圍。
表達式 |
說明 |
\d |
任意一個數字,相當於[0-9],即0~9 中的任意一個 |
\w |
任意一個字母或數字或下劃線,相當於[a-zA-Z0-9_] |
\s |
任意空白字符,相當於[ \r\n\f\t\v] |
\D |
任意一個非數字字符,\d取反,相當於[^0-9] |
\W |
\w取反,相當於[^a-zA-Z0-9_] |
\S |
任意非空白字符,\s取反,相當於[^ \r\n\f\t\v] |
舉例:
“\w\s\d”在匹配“Windows 2003”時,匹配成功,匹配的結果爲“s 2”。
2.2.3 . 小數點
小數點可以匹配除“\n”以外的任意一個字符。如果要匹配包括“\n”在內的所有字符,一般用[\s\S],或者是用“.”加(?s)匹配模式來實現。
表達式 |
說明 |
. |
匹配除了換行符 \n 以外的任意一個字符 |
2.2.4 其它元字符
表達式 |
說明 |
^ |
匹配字符串開始的位置,不匹配任何字符 |
$ |
匹配字符串結束的位置,不匹配任何字符 |
\b |
匹配單詞邊界,不匹配任何字符 |
舉例:
“^a”在匹配“cba”時,匹配失敗,因爲表達式要求開始位置後面是字符“a”,而“cba”顯然是不滿足的。
“\d$”在匹配“123”時,匹配成功,匹配結果爲“3”,這個表達式要求匹配結尾處的數字,如果結尾處不是數字,如“123abc”,則是匹配失敗的。
2.2.5 轉義字符
一些不可見字符,或是在正則中具有特殊意義的元字符,如想匹配字符本身,需要用“\”對其進行轉義。
表達式 |
說明 |
\r,\n |
回車和換行 |
\\ |
匹配“\”本身 |
\^,\$,\. |
分別匹配“^”、“$”和“.” |
以下字符在匹配其本身時,通常需要進行轉義。在實際應用中,根據具體情況,需要轉義的字符可能不止如下所列字符
. $ ^ { [ ( | ) * + ? \
2.2.6 量詞(Quantifier)
量詞表示一個子表達式可以匹配的次數。量詞可以用來修飾一個字符、字符組,或是用()括起來的子表達式。一些常用的量詞被定義成獨立的元字符。
表達式 |
說明 |
舉例 |
{m} |
表達式匹配m次 |
“\d{3}”相當於“\d\d\d ” “(abc){2}”相當於“abcabc” |
{m,n} |
表達式匹配最少m次,最多n次 |
“\d{2,3}”可以匹配“12”或“321”等2到3位的數字 |
{m,} |
表達式至少匹配m次 |
“[a-z]{8,}”表示至少8位以上的字母 |
? |
表達式匹配0次或1次,相當於{0,1} |
“ab?”可以匹配“a”或“ab” |
* |
表達式匹配0次或任意多次,相當於{0,} |
“<[^>]*>”中“[^>]*”表示0個或任意多個不是“>”的字符 |
+ |
表達式匹配1次或意多次,至少1次,相當於{1,} |
“\d\s+\d”表示兩個數字中間,至少有一個以上的空白字符 |
注意:在不是動態生成的正則表達式中,不要出現“{1}”這樣的量詞,如“\w{1}”在結果上等價於“\w”,但是會降低匹配效率和可讀性,屬於畫蛇添足的做法。
2.2.7 分支結構(Alternation)
當一個字符串的某一子串具有多種可能時,採用分支結構來匹配,“|”表示多個子表達式之間“或”的關係,“|”是以()限定範圍的,如果在“|”的左右兩側沒有()來限定範圍,那麼它的作用範圍即爲“|”左右兩側整體。
表達式 |
說明 |
| |
多個子表達式之間取“或”的關係 |
舉例:
“^aa|b$”在匹配“cccb”時,是可以匹配成功的,匹配的結果是“b”,因爲這個表達式表示匹配“^aa”或“b$”,而“b$”在匹配“cccb ”時是可以匹配成功的。
“^(aa|b)$”在區配“cccb”時,是匹配失敗的,因爲這個表達式表示在“開始”和“結束”位置之間只能是“aa”或“b”,而“cccb”顯然是不滿足的。
3 正則表達式進階
3.1 捕獲組(Capture Group)
捕獲組就是把正則表達式中子表達式匹配的內容,保存到內存中以數字編號或手動命名的組裏,以供後面引用。
表達式 |
說明 |
(Expression) |
普通捕獲組,將子表達式Expression匹配的內容保存到以數字編號的組裏 |
(?<name> Expression) |
命名捕獲組,將子表達式Expression匹配的內容保存到以name命名的組裏 |
普通捕獲組(在不產生歧義的情況下,簡稱捕獲組)是以數字進行編號的,編號規則是以“(”從左到右出現的順序,從1開始進行編號。通常情況下,編號爲0的組表示整個表達式匹配的內容。
命名捕獲組可以通過捕獲組名,而不是序號對捕獲內容進行引用,提供了更便捷的引用方式,不用關注捕獲組的序號,也不用擔心表達式部分變更會導致引用錯誤的捕獲組。
3.2 非捕獲組
一些表達式中,不得不使用( ),但又不需要保存( )中子表達式匹配的內容,這時可以用非捕獲組來抵消使用( )帶來的副作用。
表達式 |
說明 |
(?:Expression) |
進行子表達式Expression的匹配,並將匹配內容保存到最終的整個表達式的區配結果中,但Expression匹配的內容不單獨保存到一個組內 |
3.3 反向引用
捕獲組匹配的內容,可以在正則表達式的外部程序中進行引用,也可以在表達式中進行引用,表達式中引用的方式就是反向引用。
反向引用通常用來查找重複的子串,或是限定某一子串成對出現。
表達式 |
說明 |
\1,\2 |
對序號爲1和2的捕獲組的反向引用 |
\k<name> |
對命名爲name的捕獲組的反向引用 |
舉例:
“(a|b)\1”在匹配“abaa”時,匹配成功,匹配到的結果是“aa”。“(a|b)”在嘗試匹配時,雖然既可以匹配“a”,也可以匹配“b”,但是在進行反向引用時,對應()中匹配的內容已經是固定的了。
3.4 環視(Look Around)
環視只進行子表達式的匹配,匹配內容不計入最終的匹配結果,是零寬度的。
環視按照方向劃分有順序和逆序兩種,按照是否匹配有肯定和否定兩種,組合起來就有四種環視。環視相當於對所在位置加了一個附加條件。
表達式 |
說明 |
(?<=Expression) |
逆序肯定環視,表示所在位置左側能夠匹配Expression |
(?<!Expression) |
逆序否定環視,表示所在位置左側不能匹配Expression |
(?=Expression) |
順序肯定環視,表示所在位置右側能夠匹配Expression |
(?!Expression) |
順序否定環視,表示所在位置右側不能匹配Expression |
舉例:
“(?<=Windows )\d+”在匹配“Windows 2003”時,匹配成功,匹配結果爲“2003”。我們知道“\d+”表示匹配一個以上的數字,而“(?<=Windows )”相當於一個附加條件,表示所在位置左側必須爲“Windows ”,它所匹配的內容並不計入匹配結果。同樣的正則在匹配“Office 2003”時,匹配失敗,因爲這裏任意一串數字子串的左側都不是“Windows ”。
“(?!1)\d+”在匹配“123”時,匹配成功,匹配的結果爲“23”。“\d+”匹配一個以上數字,但是附加條件“(?!1)”要求所在位置右側不能是“1”,所以匹配成功的位置是“2”前面的位置。
3.5 忽略優先和匹配優先
或者叫做正則表達式匹配的貪婪與非貪婪模式。
標準量詞修飾的子表達式,在可匹配可不匹配的情況下,總會先嚐試進行匹配,稱這種方式爲匹配優先,或者貪婪模式。此前介紹的一些量詞,“{m}”、“{m,n}”、“{m,}”、“?”、“*”和“+”都是匹配優先的。
一些NFA正則引擎支持忽略優先量詞,也就是在標準量詞後加一個“?”,此時,在可匹配可不匹配的情況下,總會先忽略匹配,只有在由忽略優先量詞修飾的子表達式,必須進行匹配才能使整個表達式匹配成功時,纔會進行匹配,稱這種方式爲忽略優先,或者非貪婪模式。忽略優先量詞包括“{m}?”、“{m,n}?”、“{m,}?”、“??”、“*?”和“+?”。
舉例:
源字符串:<div>aaa</div><div>bbb</div>
正則表達式1:<div>.*</div> 匹配結果:<div>aaa</div><div>bbb</div>
正則表達式2:<div>.*?</div> 匹配結果:<div>aaa</div>