學(xué)習(xí)資料:《正則表達(dá)式必知必會(huì)》人民郵電出版社
正則表達(dá)式測(cè)試工具:http://regexr.com/
1.匹配單個(gè)字符
1.1匹配純文本
格式:
text
說明:匹配text文本
例子:
1.2匹配任意字符
格式:
.
說明:如果想匹配任意一個(gè)字符,可將這個(gè)字符的位置用.
代替,比如想匹配cat或cot,即中間的字符可能是a也可能是o,那么就正則式就可以這么寫:c.t
。
例子:
1.3匹配特殊字符
格式:
\字符
說明:拿上面的例子來說,有時(shí)候我們只想匹配.這個(gè)字符,而如果直接寫.的話就會(huì)匹配一個(gè)任意字符,所以針對(duì)這種情況,可以使用轉(zhuǎn)義字符\表明后面的字符有特殊含義,而不是字符本身的含義。比如上一個(gè)例子,如果只想匹配一個(gè).
,那可以寫成\.
。
例子:
2.匹配一組字符
2.1匹配多個(gè)字符中的某一個(gè)
格式:
[字符集合]
說明:拿之前cat和cot的例子來說,如果用c.t
,那么同時(shí)會(huì)匹配到crt、cct這些字符,因?yàn)橹虚g那個(gè)字符是任意的,而如果我們只想匹配cat和cot這兩個(gè)文本,那么就可以使用[],在方括號(hào)里定義可能出現(xiàn)的字符集合,這樣在匹配時(shí),只要字符是在這個(gè)帶匹配的字符集合里的都能匹配成功。所以如果想匹配cat和cot,那么就可以寫成:c[ao]t
。
例子:
2.2字符集合區(qū)間
格式:[字符集合區(qū)間]
說明:如果我們要匹配的那個(gè)位置可以是任何一個(gè)英文字符,我們?cè)撛趺磳懀堪阉锌赡艹霈F(xiàn)的英文字符都寫一遍么?那就是[abcdefghijklmnopqrstuvwxyz]
,這才只是小寫字母,如果我在加上大寫字母和數(shù)字呢?是不是要瘋掉了,所以字符區(qū)間就是解決這個(gè)問題,如果我們要匹配a-z的小寫字母就可以這么寫:[a-z]
,是不是比之前的寫法簡單多了。針對(duì)常用的幾種匹配內(nèi)容,正則表達(dá)式可以支持以下一些區(qū)間:
- A-Z:匹配從A到Z的所有大寫字母
- a-z:匹配從a-z的所有小寫字母
- 0-9:匹配從0-9的所有數(shù)字
例子:
2.3取非匹配
格式:
[^字符集合]
說明:之前我們說的是匹配字符集合中的字符,那么問題來了,如果我們想匹配除了a的所有字符,那怎么辦?(吐個(gè)槽,a到底跟你多大仇,就是不匹配它)總不能一個(gè)個(gè)列舉可能出現(xiàn)的字符吧。所以我們可以使用取非匹配,排除掉一個(gè)a,其他字符都可以匹配,寫成:[^a]
,這樣就能匹配除了a的任意字符了。
例子:
3.使用元字符
3.1對(duì)特殊字符進(jìn)行轉(zhuǎn)義
格式:
\元字符
說明:這其實(shí)是在1.3中講的內(nèi)容,所謂元字符,就是在正則表達(dá)式中有特殊含義的字符,比如[、]、.包括\,他們匹配的字符并不是他們本身。但如果我們確實(shí)要匹配他們本身的時(shí)候,需要用\加上該字符來匹配字符本身。
例子:
- 匹配一個(gè)數(shù)組項(xiàng)
array\[0\]
- 匹配文件目錄
\\home\\src\\bin
3.2匹配空白字符
格式:
\元字符
說明:當(dāng)需要找出原始文本中的空白字符或者換行符是怎么辦呢?系統(tǒng)內(nèi)置的幾個(gè)元字符可是實(shí)現(xiàn)該功能。
- [\b] 回退(并刪除)一個(gè)字符
- \f 換頁符
- \n 換行符
- \r 回車符
- \t 制表符
- \v 垂直制表符
3.3匹配特定的字符類別
-
匹配數(shù)字與非數(shù)字
格式:\d
、\D
說明:之前說匹配數(shù)字可以用[0-9]
,其實(shí)更簡單的寫法是\d
,兩者的意思是等價(jià)的。同理[^0-9]
與\D
也是等價(jià)的,表示匹配除了0-9的任意字符(非數(shù)字的字符)。
例子:匹配數(shù)組任意一項(xiàng)array\[\d\]
-
匹配數(shù)字和字符與非數(shù)字和字母
格式:\w
、\W
說明:\w
匹配任何一個(gè)字母或數(shù)字(大小寫均可)或下劃線,等價(jià)于[a-zA-z0-9_]
\W
匹配任何一個(gè)非字母或數(shù)字(大小寫均可)或下劃線,等價(jià)于[^a-zA-z0-9_]
例子:
-
匹配空白字符與非空白字符
格式:\s
、\S
說明:\s
匹配任何一個(gè)空白字符,等價(jià)于[\f\n\r\t\v]
\S
匹配任何一個(gè)非空白字符,等價(jià)于[^\f\n\r\t\v]
例子:
-
匹配十六進(jìn)制值與八進(jìn)制值
格式:\x
、\0
說明:\x
匹配十六進(jìn)制數(shù)的前綴
\0
匹配八進(jìn)制數(shù)的前綴
例子:-
\x48
值為72,對(duì)應(yīng)的ASCII碼是H
-
\047
值為39,對(duì)應(yīng)的ASCII碼是'
-
4.重復(fù)匹配
4.1有多少個(gè)匹配
-
匹配一個(gè)或多個(gè)
格式:字符+
、[字符集合]+
說明:如果想匹配一個(gè)字符或字符集合的多次重復(fù),那么可以使用+
作為后綴。比如,a+表示匹配一個(gè)或多個(gè)連續(xù)出現(xiàn)的a,[0-9]+表示匹配一個(gè)或多個(gè)連續(xù)出現(xiàn)的數(shù)字。
例子:
-
匹配零個(gè)或多個(gè)字符
格式:字符*
、[字符集合]*
說明:+
至少需要匹配一個(gè)字符,而*
匹配的字符則是可有可無。
例子:
-
匹配零個(gè)或一個(gè)字符
格式:字符?
、[字符集合]?
說明:?匹配的字符要么出現(xiàn),要么只出現(xiàn)一次,只有這兩種情況。
例子:
4.2匹配的重復(fù)次數(shù)
-
為重復(fù)匹配次數(shù)設(shè)定一個(gè)精確值
格式:字符{重復(fù)次數(shù)}
、[字符集合]{重復(fù)次數(shù)}
說明:雖然之前說的+ * ?
功能很強(qiáng)大,但是很多情況下并不能滿足要求,比如要匹配一個(gè)11位數(shù)的電話號(hào)碼顯然用任意一個(gè)功能都完不成。這時(shí)就需要引入重復(fù)次數(shù),比如[0-9]{11}
就表示匹配連續(xù)11個(gè)出現(xiàn)的數(shù)字,這就能匹配像電話號(hào)碼這樣的要求(當(dāng)然可能還有更詳細(xì)地約束,比如必須以1開頭,這里只是舉個(gè)簡單的例子)。
例子:
-
為重復(fù)匹配次數(shù)設(shè)定一個(gè)區(qū)間
格式:字符{最少重復(fù)次數(shù),最多重復(fù)次數(shù)}
、[字符集合]{最少重復(fù)次數(shù),最多重復(fù)次數(shù)}
說明:為重復(fù)次數(shù)設(shè)定一個(gè)最小值和最大值,表明一個(gè)字符或字符集合最少出現(xiàn)的次數(shù)和最多出現(xiàn)的次數(shù)。
例子:
-
匹配至少重復(fù)多少次
格式:字符{最少重復(fù)次數(shù),}
、[字符集合]{最少重復(fù)次數(shù),}
說明:有了第2點(diǎn)介紹的只是,這里就很好理解,為重復(fù)次數(shù)設(shè)定一個(gè)最小值,不設(shè)定最大值,那不就是表明一個(gè)字符至少出現(xiàn)多少次嘛!
例子:
4.3防止過度匹配
說明:之前介紹的+*{n,}都沒有定義匹配次數(shù)的上限,這就很容易造成過度匹配的現(xiàn)象。所以有必要引入“貪婪型”字符和“懶惰型”字符的概念。
貪婪型字符有:
*、+、{n,}
對(duì)應(yīng)的懶惰型字符有:
*?、+?、{n,}?
比如一個(gè)h5的頁面有很多<h2>...</h2>
這樣的標(biāo)簽,如果我們使用貪婪型字符匹配可以寫成:
<h2>.*</h2>
貪婪型字符*的匹配原則是,只要沒匹配到最后一個(gè)</h2>
,我就一直匹配下去,直到匹配到最后一個(gè)</h2>
。
使用懶惰型字符匹配可以寫成
<h2>.*?</h2>
懶惰型字符*?的匹配原則是,只要我匹配到了后面的一個(gè)</h2>
,我就不干了,不匹配了,除非找到下一個(gè)<h2>
,我再繼續(xù)匹配。
例子:
-
貪婪型字符匹配
-
懶惰型字符匹配
5.位置匹配
5.1單詞邊界
格式:\b單詞\b
、\b單詞
、單詞\b
說明:什么是邊界匹配呢?舉個(gè)簡單的例子,比如一篇英文文章,我想找其中的cat單詞,于是我這么寫:cat
,看起來是沒問題,但是實(shí)際匹配的時(shí)候會(huì)將所有cat都找出來,當(dāng)然cat這個(gè)單詞能找出來是毋庸置疑的,但同時(shí)會(huì)將類似scattered這樣包含cat的單詞也找出來,著當(dāng)然不是我們所期望的,于是引入單詞邊界的概念,在cat前后各加上一個(gè)\b表示這中間是一個(gè)單詞,\b用來匹配一個(gè)單詞的開始或結(jié)尾。注意:只有\bcat\b
才表示要匹配cat這個(gè)單詞,而\bcat
、cat\b
則分別表示匹配以cat開頭和以cat結(jié)尾的單詞。
例子:
-
不帶單詞邊界匹配
-
帶單詞邊界匹配
-
匹配cat開頭的單詞
-
匹配cat結(jié)尾的單詞
5.2字符串邊界
格式:^字符串$
、^字符串
、字符串$
說明:與單詞邊界同理,字符串邊界表示字符串的開頭與結(jié)尾,分別用^、$表示。
例子:
-
cat開頭字符串
-
bar結(jié)尾字符串
6.子表達(dá)式
6.1什么是子表達(dá)式
格式:
(子表達(dá)式)
說明:前面我們學(xué)過如何指定重復(fù)次數(shù),用的是字符{重復(fù)次數(shù)}
或[字符集合]{重復(fù)次數(shù)}
,這里的重復(fù)次數(shù)只是前面的字符或者字符集合,加入我想將\d{1,3}\.
這樣一個(gè)完整的表達(dá)式重復(fù)幾次,那怎么辦呢?我們可以用()將這樣的表達(dá)式包裹起來,將括號(hào)的內(nèi)容作為一個(gè)整體,再進(jìn)行重復(fù)次數(shù)的表示,比如如果想找出連續(xù)出現(xiàn)3次cat單詞,可以寫成這樣:(\d{1,3}\.){3}
例子:匹配IP地址
6.2子表達(dá)式的嵌套
格式:
((子表達(dá)式1)|(子表達(dá)式2))
說明:子表達(dá)式是允許嵌套的,舉個(gè)例子,如果我們想匹配一串IP地址,12.159.46.200,略加思考我們不難能寫出這樣的正則表達(dá)式:(\d{1,3}\.){3}\d{1,3}
,但是其實(shí)這個(gè)表達(dá)式并不等價(jià)于IP地址,999.999.999.999明顯不是一個(gè)IP地址,但是它是符合這個(gè)規(guī)則的,所以我們要對(duì)這個(gè)表達(dá)式中的數(shù)字要求做出修改,IP地址的四個(gè)組成部分必須符合以下要求:
- 任何一個(gè)1位數(shù)字或2位數(shù)字(0-99)——
\d{1,2}
- 任何一個(gè)以1開頭的3位數(shù)字(100-199)——
1\d{2}
- 任何一個(gè)以2開頭,第2位在0-4之間的3位數(shù)字(200-249)——
2[0-4]\d
- 任何一個(gè)以25開頭,第3位在0-5之間的3位數(shù)字(250-255)——
25[0-5]
所以根據(jù)以上規(guī)則將原表達(dá)式改寫為:
((((25[0-5])|(2[0-4]\d)|(1\d{2})|\d{1,2})|)\.){3}(((25[0-5])|(2[0-4]\d)|(1\d{2})|\d{1,2})|)
例子:
注意:這里將詳細(xì)地規(guī)則寫在前面,比如匹配200,如果檢測(cè)到20是滿足
\d{1,2}
的,就不會(huì)再去看后面的0了