什么是正則表達(dá)式
正則表達(dá)式就是用一個(gè)“字符串”來描述一個(gè)特征,然后去驗(yàn)證另一個(gè)“字符串”是否符合這個(gè)特征。簡單的一個(gè)例子:用字符串”a”來驗(yàn)證字符串s是否是”a”,形如s.match(“a”)。概括來說有以下作用:
-
驗(yàn)證字符串是否符合指定特征,比如驗(yàn)證是否是合法的郵件地址。
-
查找字符串,從一個(gè)長的文本中查找符合指定特征的字符串,比查找固定字符串更加靈活。
-
替換字符串,比普通的基于字符串的替換更靈活。
基本規(guī)則
普通字符
字母、數(shù)字、漢字、下劃線、以及后續(xù)沒有特殊定義的標(biāo)點(diǎn)符號,都是”普通字符”。表達(dá)式中的普通字符,在匹配一個(gè)字符串的時(shí)候,匹配與之相同的一個(gè)字符。如:表達(dá)式 “a”,在匹配字符串 “abcde” 時(shí),匹配到的內(nèi)容是:“a”。
轉(zhuǎn)義字符
一些不便書寫的字符,采用在前面加 “” 的方法。常見的如:
-
: 回車
-
: 換行符
-
: 制表符
-
: “”?本身
此外,還有其他再正則中有特殊用處的標(biāo)點(diǎn)符號,在前面加 “”后,代表該符號本身。如:^, “ 字符,需要寫成 “^” 和?“$”。如
-
^: 匹配^符號本身
-
$: 匹配$符號本身
-
.: 匹配小數(shù)點(diǎn). 本身
其匹配規(guī)則和普通字符串是一樣的,如“^”匹配“a^bc”中的“^”。
‘多種字符’匹配
-
d:任意一個(gè)數(shù)字,0~9 中的任意一個(gè)
-
w:任意一個(gè)字母或數(shù)字或下劃線,也就是 A~Z,a~z,0~9,_ 中任意一個(gè)
-
s:包括空格、制表符、換頁符等空白字符的其中任意一個(gè)
-
.:小數(shù)點(diǎn)可以匹配除了換行符以外的任意一個(gè)字符
如:表達(dá)式 “dtestd”匹配”1test2”。
除了正則自帶的“多種字符”匹配外,還可以通過中括號[]來自定義。
-
使用[ ]包含一系列字符,能夠匹配其中任意一個(gè)字符。
-
用 [^ ]包含一系列字符,則能夠匹配其中字符之外的任意一個(gè)字符。
如:[123]匹配 “1”或”2”或“3”;[^abc]匹配 “a”、”b”、”c” 之外的任意一個(gè)字符。
這里需要注意的是,在使用[]時(shí),只有會(huì)改變字符組含義的才需要轉(zhuǎn)義,
-
反斜線必須轉(zhuǎn)義
-
方括號必須轉(zhuǎn)義
-
「^」在首和「-」在中必須轉(zhuǎn)義
其他情況即使是特殊字符也不需要轉(zhuǎn)義,如:
-
[aeiou]
-
[$.*+?{}()|]
-
[abc^123-]
匹配次數(shù)
“次數(shù)修飾”放在”被修飾的正則表達(dá)式”后邊,可以匹配多次。如:
-
{n}: 表達(dá)式重復(fù)n次,比如:“d{2}” 相當(dāng)于 “dd”。
-
{m,n}:表達(dá)式至少重復(fù)m次,最多重復(fù)n次,比如:“a{1,3}”可以匹配 “a”或”aa”或”aaa”。
-
{m,}: 表達(dá)式至少重復(fù)m次,比如:“d{2,}”可以匹配 “12”,“123”,“12345678”。
-
?: 匹配表達(dá)式0次或者1次,相當(dāng)于 {0,1},比如:“a[b]?”可以匹配”a”,“ab”。
-
+: 表達(dá)式至少出現(xiàn)1次,相當(dāng)于 {1,},比如:“a+”可以匹配”a”,“aa”,“aaa”。
-
*: 表達(dá)式不出現(xiàn)或出現(xiàn)任意次,相當(dāng)于 {0,},比如:”ab“可以匹配 “a”、”ab”、”abb”。
特殊符號
-
^: 與字符串開始的地方匹配,不匹配任何字符,這里如果使用(?m)模式,則匹配每一行的開始。如:“^aaa”無法匹配 “xxxaaaxxx”,可以匹配”aaaxxx”。
-
$: 與字符串結(jié)束的地方匹配,不匹配任何字符,這里如果使用(?m)模式,則匹配每一行的結(jié)束。如:“aaa$”無法匹配“xxxaaaxxx”, 可以匹配“xxxaaa”。
-
:匹配一個(gè)單詞邊界,也就是單詞和空格之間的位置,不匹配任何字符。它與 “^”、”$“ 類似,本身不匹配任何字符,但是它要求它在匹配結(jié)果中所處位置的左右兩邊,其中一邊是 “w” 范圍,另一邊是 非“w” 的范圍。。如:“..”匹配“@@abc”的“@a”。
此外,還有一些符號可以影響表達(dá)式內(nèi)部的子表達(dá)式之間的關(guān)系:
-
|: 左右兩邊表達(dá)式之間“或”關(guān)系,匹配左邊或者右邊。
-
(): 在被修飾匹配次數(shù)的時(shí)候,括號中的表達(dá)式可以作為整體被修飾;取匹配結(jié)果的時(shí)候,括號中的表達(dá)式匹配到的內(nèi)容可以被單獨(dú)得到。如:”(abs*)+“匹配”hi, ab ab ab”中的“ab ab ab”。
高級規(guī)則
貪婪與非貪婪匹配
在使用修飾匹配次數(shù)的特殊符號時(shí),有幾種表示方法可以使同一個(gè)表達(dá)式能夠匹配不同的次數(shù),比如:“{m,n}”, “{m,}”, “?”, “*”,?“+”,具體匹配的次數(shù)隨被匹配的字符串而定。這種重復(fù)匹配不定次數(shù)的表達(dá)式在匹配過程中,總是盡可能多的匹配。
比如,文本 “axxxaxxxa”,”(a)(w+)“,其中”w+“會(huì)匹配”xxxaxxxa”,”(a)(w+)(a)“則會(huì)匹配”xxxaxxx”。由此可見,”w+“ 在匹配的時(shí)候,總是盡可能多的匹配符合它規(guī)則的字符。
雖然第二個(gè)舉例中,它沒有匹配最后一個(gè) “a”,但那也是為了讓整個(gè)表達(dá)式能夠匹配成功。同樣的,帶 ”“ 和 ”{m,n}“ 的表達(dá)式都是盡可能地多匹配,帶 ”?“ 的表達(dá)式在可匹配可不匹配的時(shí)候,也是盡可能的匹配。這種匹配原則就叫作”貪婪”模式。
非貪婪模式則是指的在修飾匹配次數(shù)的特殊符號后再加上一個(gè) “?” 號,可以使匹配次數(shù)不定的表達(dá)式盡可能少的匹配,使可匹配可不匹配的表達(dá)式,盡可能的不匹配。
這種匹配原則也叫作 “勉強(qiáng)” 模式。如果少匹配就會(huì)導(dǎo)致整個(gè)表達(dá)式匹配失敗的時(shí)候,與貪婪模式類似,非貪婪模式會(huì)最小限度的再匹配一些,以使整個(gè)表達(dá)式匹配成功。如,文本 “axxxaxxxa” ,“(a)(w+?)”,其中”w+“只會(huì)匹配一個(gè)“x”。
反向引用
表達(dá)式在匹配時(shí),表達(dá)式引擎會(huì)將小括號 “()” 包含的表達(dá)式所匹配到的字符串記錄下來。在獲取匹配結(jié)果的時(shí)候,小括號包含的表達(dá)式所匹配到的字符串可以單獨(dú)獲取。當(dāng)用某種邊界來查找,而所要獲取的內(nèi)容又不包含邊界時(shí),必須使用小括號來指定所要的范圍。如:“
這里小括號包含的正則表達(dá)式所匹配到的字符串不僅僅是在匹配結(jié)束后才可以使用,在匹配過程中也可以使用。表達(dá)式后邊的部分,可以引用前面括號內(nèi)的子匹配已經(jīng)匹配到的字符串。引用方法是 “” 加上一個(gè)數(shù)字?!?” 引用第1對括號內(nèi)匹配到的字符串,”2” 引用第2對括號內(nèi)匹配到的字符串,以此類推,而如果一對括號內(nèi)包含另一對括號,則外層的括號先排序號。換句話說,哪一對的左括號 “(” 在前,那這一對就先排序號。
例如:表達(dá)式 “(‘|’)(.*?)(1)“ 在匹配 ”?‘Hello’, “World” “ 時(shí),匹配結(jié)果是:成功;匹配到的內(nèi)容是:” ‘Hello’ “。再次匹配下一個(gè)時(shí),可以匹配到 ” “World” “。
?
預(yù)搜索
如前面所講”^“、”$“、””字符有一個(gè)共同點(diǎn),就是:它們本身不匹配任何字符,只是對 “字符串的兩頭” 或者 “字符之間的縫隙” 附加了一個(gè)條件。同樣的,正則中提供了其他基于此原理的機(jī)制,來實(shí)現(xiàn)預(yù)搜索。
-
正向預(yù)搜索:”(?=xxxxx)“,”(?!xxxxx)”
格式:”(?=xxxxx)“,在被匹配的字符串中,它對所處的 “縫隙” 或者 “兩頭” 附加的條件是:所在縫隙的右側(cè),必須能夠匹配上xxxxx這部分的表達(dá)式,不影響后邊的表達(dá)式去真正匹配這個(gè)縫隙之后的字符。如:“Mac (?=book|air)” 在匹配 “Mac pro, Mac air” 時(shí),將只匹配 “Mac air” 中的 “Mac”。
格式:“(?!xxxxx)”,所在縫隙的右側(cè),必須不能匹配 xxxxx 這部分表達(dá)式。如:“hello(?!w)” 在匹配字符串 “hello,helloworld”時(shí),匹配 hello”。這里使用 “(?!w)” 和使用 “” 效果一樣。
-
反向預(yù)搜索:“(?<=xxxxx)”,“(?
和正向預(yù)搜索類似,反向預(yù)搜索要求的條件是:所在縫隙的 “左側(cè)”,兩種格式分別要求必須能夠匹配和必須不能夠匹配指定表達(dá)式,而不是去判斷右側(cè)。與 “正向預(yù)搜索” 一樣的是:它們都是對所在縫隙的一種附加條件,本身都不匹配任何字符。
其他通用規(guī)則
-
可以使用 “xXX” 和 “uXXXX” 表示一個(gè)字符(”X” 表示一個(gè)十六進(jìn)制數(shù))
-
xXX: 編號在 0-255 范圍的字符,如:空格可以使用 “x20” 表示
-
uXXXX: 任何字符可以使用 “u” 再加上其編號的4位十六進(jìn)制數(shù)表示,比如:“u4E2D”
-
-
在表達(dá)式 “s”,”d”,”w”,”” 表示特殊意義的同時(shí),對應(yīng)的大寫字母表示相反的意義
-
S: 匹配所有非空白字符
-
D: 匹配所有的非數(shù)字字符
-
W: 匹配所有的字母、數(shù)字、下劃線以外的字符
-
B: 匹配非單詞邊界,即左右兩邊都是 “w” 范圍或者左右兩邊都不是 “w” 范圍時(shí)的字符縫隙
-
-
括號“()”內(nèi)的子表達(dá)式,如果希望匹配結(jié)果不進(jìn)行記錄供以后使用,可以使用 “(?:xxxxx)”格式。如:表達(dá)式 “(?:(w)1)+” 匹配 “a bbccdd efg” 時(shí),結(jié)果是 “bbccdd”。括號 “(?:)” 范圍的匹配結(jié)果不進(jìn)行記錄,因此 “(w)” 使用 “1” 來引用。
-
常用的表達(dá)式屬性設(shè)置包括:Ignorecase、Singleline、Multiline、Global
-
Ignorecase: 默認(rèn)情況下,表達(dá)式中的字母是要區(qū)分大小寫的。配置為 Ignorecase 可使匹配時(shí)不區(qū)分大小寫。有的表達(dá)式引擎,把 “大小寫” 概念延伸至 UNICODE 范圍的大小寫。
-
Singleline: 默認(rèn)情況下,小數(shù)點(diǎn) “.” 匹配除了換行符( )以外的字符。配置為Singleline可使小數(shù)點(diǎn)可匹配包括換行符在內(nèi)的所有字符。
-
Multiline: 默認(rèn)情況下,表達(dá)式 “^” 和 “$” 只匹配字符串的開始1和結(jié)尾4位置。如:1xxxxxxxxx2 3xxxxxxxxx4
-
配置為 Multiline 可以使 “^” 匹配1外,還可以匹配換行符之后,下一行開始前3的位置,”$“ 匹配4外,還可以匹配換行符之前,一行結(jié)束2的位置。使用(?m)可以設(shè)置為Multiline模式。如”(?m)^ +“。
-
Global: 主要在將表達(dá)式用來替換時(shí)起作用,配置為Global表示替換所有的匹配。
提示
-
如果要求表達(dá)式所匹配的內(nèi)容是整個(gè)字符串,而不是其中的一部分,可以在表達(dá)式的首尾使用 “^” 和 ““?要求整個(gè)字符串只有數(shù)字。
-
如果要求匹配的內(nèi)容是一個(gè)完整的單詞,而不會(huì)是單詞的一部分,那么在表達(dá)式首尾使用 “”,如:使用 “(if|while|…)” 來匹配程序中的關(guān)鍵字。
-
表達(dá)式不要匹配空字符串。否則會(huì)一直得到匹配成功,而結(jié)果什么都沒有匹配到。
-
能匹配空字符串的子匹配不要循環(huán)無限次。如果括號內(nèi)的子表達(dá)式中的每一部分都可以匹配0次,而這個(gè)括號整體又可以匹配無限次,那么匹配過程中可能死循環(huán)。
-
“|” 的左右兩邊,對某個(gè)字符應(yīng)該只有一邊可以匹配,以防止”|“兩邊的表達(dá)式因?yàn)榻粨Q位置而有所不同。
-
要合理選擇貪婪模式與非貪婪模式,如.?與?.?的區(qū)別使用。
審核編輯:湯梓紅
評論
查看更多