正則表達(dá)式
場(chǎng)景
1.在一個(gè)文件中醉蚁,查找出hello開頭的語(yǔ)句
2.在一個(gè)文件中,找到含有hello的語(yǔ)句
3.在一個(gè)文件中侦锯,找到郵箱為163的所有郵件地址
正則表達(dá)式(regular expression)是一種工具镀娶,一種廣泛用于匹配字符串的工具缨历。它用一個(gè)“字符串”來(lái)描述一個(gè)特征猩谊,然后去驗(yàn)證另一個(gè)“字符串”是否符合這個(gè)特征千劈。比如 表達(dá)式“ab+”描述的特征是“一個(gè)'a'和任意個(gè)'b'”,那么'ab','abb','abbbbbbbbbb'都符合這個(gè)特征牌捷。
正則表達(dá)式語(yǔ)法
正則表達(dá)式本質(zhì)上只做一件事墙牌,那就是編寫一個(gè)表達(dá)式“字符串”,然后用這個(gè)字符串去匹配目標(biāo)文本暗甥。核心的核心喜滨,都在編寫這個(gè)“字符串”表達(dá)式上面。
普通字符
字母淋袖、數(shù)字鸿市、漢字锯梁、下劃線即碗、以及沒(méi)有特殊定義的符號(hào)焰情,都是"普通字符"。正則表達(dá)式中的普通字符剥懒,在匹配的時(shí)候,只匹配與自身相同的一個(gè)字符内舟。
例如:表達(dá)式c
,在匹配字符串abcde
時(shí)初橘,匹配結(jié)果是:成功验游;匹配到的內(nèi)容是c
;匹配到的位置開始于2保檐,結(jié)束于3耕蝉。(注:下標(biāo)從0開始還是從1開始,因當(dāng)前編程語(yǔ)言的不同而可能不同)
元字符
正則表達(dá)式中使用了很多元字符夜只,用來(lái)表示一些特殊的含義或功能垒在。
表達(dá)式 | 匹配 |
---|---|
. |
小數(shù)點(diǎn)可以匹配除了換行符\n 以外的任意一個(gè)字符 |
| |
邏輯或操作符 |
[] |
匹配字符集中的一個(gè)字符 |
[^] |
對(duì)字符集求反,也就是上面的反操作扔亥。尖號(hào)必須在方括號(hào)里的最前面 |
- |
定義[] 里的一個(gè)字符區(qū)間场躯,例如[a-z]
|
\ |
對(duì)緊跟其后的一個(gè)字符進(jìn)行轉(zhuǎn)義 |
() |
對(duì)表達(dá)式進(jìn)行分組,將圓括號(hào)內(nèi)的內(nèi)容當(dāng)做一個(gè)整體旅挤,并獲得匹配的值 |
例如:
a.c匹配abc
(a|b)c匹配ac與bc
[abc]1匹配a1或者b1或者c1
使用方括號(hào)[]包含一系列字符踢关,能夠匹配其中任意一個(gè)字符。用[^]包含一系列字符粘茄,則能夠匹配其中字符之外的任意一個(gè)字符签舞。
[ab5@]匹配a或b或5或@
[^abc]匹配a,b,c之外的任意一個(gè)字符
[f-k]匹配f~k 之間的任意一個(gè)字母
[^A-F0-3]匹配A~F以及0~3之外的任意一個(gè)字符
轉(zhuǎn)義字符
一些無(wú)法書寫或者具有特殊功能的字符,采用在前面加斜杠""進(jìn)行轉(zhuǎn)義的方法柒瓣。例如下表所示:
表達(dá)式 | 匹配 |
---|---|
\r , \n
|
匹配回車和換行符 |
\t |
匹配制表符 |
\\ |
匹配斜杠\
|
\^ |
匹配^ 符號(hào) |
\$ |
匹配$符號(hào) |
\. |
匹配小數(shù)點(diǎn).
|
尚未列出的還有問(wèn)號(hào)瘪菌?、星號(hào)*和括號(hào)等其他的符號(hào)嘹朗。所有正則表達(dá)式中具有特殊含義的字符在匹配自身的時(shí)候师妙,都要使用斜杠進(jìn)行轉(zhuǎn)義。這些轉(zhuǎn)義字符的匹配方法與普通字符類似屹培,也是匹配與之相同的一個(gè)字符默穴。
預(yù)定義匹配字符集
正則表達(dá)式中的一些表示方法,可以同時(shí)匹配某個(gè)預(yù)定義字符集中的任意一個(gè)字符褪秀。比如蓄诽,表達(dá)式\d
可以匹配任意一個(gè)數(shù)字。雖然可以匹配其中任意字符媒吗,但是只能是一個(gè)仑氛,不是多個(gè)。
表達(dá)式 | 匹配 |
---|---|
\d |
任意一個(gè)數(shù)字,0~9 中的任意一個(gè) |
\w |
任意一個(gè)字母或數(shù)字或下劃線锯岖,也就是 A-Z,a-z,0-9,_ 中的任意一個(gè) |
\s |
空格介袜、制表符、換頁(yè)符等空白字符的其中任意一個(gè) |
\D |
\d 的反集出吹,也就是非數(shù)字的任意一個(gè)字符遇伞,等同于[^\d]
|
\W |
\w 的反集,也就是[^\w]
|
\S |
\s 的反集捶牢,也就是[^\s]
|
例如表達(dá)式\d\d
鸠珠,在匹配abc123
時(shí),匹配的結(jié)果是:成功秋麸;匹配到的內(nèi)容是12
渐排;匹配到的位置開始于3,結(jié)束于5灸蟆。 (前提是用search來(lái)匹配飞盆,用match是匹配不到的)
重復(fù)匹配
前面的表達(dá)式,無(wú)論是只能匹配一種字符的表達(dá)式次乓,還是可以匹配多種字符其中任意一個(gè)的表達(dá)式吓歇,都只能匹配一次。但是有時(shí)候我們需要對(duì)某個(gè)片段進(jìn)行重復(fù)匹配票腰,例如手機(jī)號(hào)碼13666666666城看,一般的新手可能會(huì)寫成\d\d\d\d\d\d\d\d\d\d\d
(注意,這不是一個(gè)恰當(dāng)?shù)谋磉_(dá)式)杏慰,不但寫著費(fèi)勁测柠,看著也累,還不一定準(zhǔn)確恰當(dāng)缘滥。
這種情況可以使用表達(dá)式再加上修飾匹配次數(shù)的特殊符號(hào){}
轰胁,不用重復(fù)書寫表達(dá)式就可以重復(fù)匹配。比如[abcd][abcd]
可以寫成[abcd]{2}
朝扼。
表達(dá)式 | 匹配 |
---|---|
{n} |
表達(dá)式重復(fù)n次赃阀,比如\d{2} 相當(dāng)于\d\d ,a{3} 相當(dāng)于aaa
|
{m,n} |
表達(dá)式至少重復(fù)m次,最多重復(fù)n次擎颖。比如ab{1,3} 可以匹配ab 或abb 或abbb
|
{m,} |
表達(dá)式至少重復(fù)m次榛斯,比如\w\d{2,} 可以匹配a12 ,_1111 ,M123 等等 |
? |
匹配表達(dá)式0次或者1次,相當(dāng)于{0,1} 搂捧,比如a[cd]? 可以匹配a ,ac ,ad
|
+ |
表達(dá)式至少出現(xiàn)1次驮俗,相當(dāng)于{1,} ,比如a+b 可以匹配ab ,aab ,aaab 等等 |
* |
表達(dá)式出現(xiàn)0次到任意次允跑,相當(dāng)于{0,} 王凑,比如\^*b 可以匹配b ,^^^b 等等 |
位置匹配
有時(shí)候搪柑,我們對(duì)匹配出現(xiàn)的位置有要求,比如開頭索烹、結(jié)尾工碾、單詞之間等等。
表達(dá)式 | 匹配 |
---|---|
^ |
在字符串開始的地方匹配术荤,符號(hào)本身不匹配任何字符 |
$ | 在字符串結(jié)束的地方匹配,符號(hào)本身不匹配任何字符 |
\b |
匹配一個(gè)單詞邊界每篷,也就是單詞和空格之間的位置瓣戚,符號(hào)本身不匹配任何字符 |
\B |
匹配非單詞邊界,即左右兩邊都是\w 范圍或者左右兩邊都不是\w 范圍時(shí)的字符縫隙 |
例如表達(dá)式^aaa
在匹配xxx aaa xxx
時(shí)焦读,匹配結(jié)果是:失敗子库。因?yàn)?code>^要求在字符串開始的地方匹配。
表達(dá)式aaa$
在匹配xxx aaa xxx
時(shí)矗晃,匹配結(jié)果是:失敗仑嗅。因?yàn)?要求在字符串結(jié)束的地方匹配。
表達(dá)式.\b.
在匹配@@@abc
時(shí)张症,匹配結(jié)果是:成功仓技;匹配到的內(nèi)容是@a
;匹配到的位置開始于2俗他,結(jié)束于4脖捻。
表達(dá)式\bend\b
在匹配weekend,endfor,end
時(shí),匹配結(jié)果是:成功兆衅;匹配到的內(nèi)容是end
地沮;匹配到的位置開始于15,結(jié)束于18羡亩。
貪婪與非貪婪模式
在重復(fù)匹配時(shí)摩疑,正則表達(dá)式默認(rèn)總是盡可能多的匹配,這被稱為貪婪模式畏铆。比如雷袋,針對(duì)文本dxxxdxxxd
,表達(dá)式(d)(\w+)(d)
中的\w+
將匹配第一個(gè)d
和最后一個(gè)d
之間的所有字符xxxdxxx
辞居∑牛可見,\w+
在匹配的時(shí)候速侈,總是盡可能多的匹配符合它規(guī)則的字符率寡。同理,帶有?
倚搬、*
和{m,n}
的重復(fù)匹配表達(dá)式都是盡可能地多匹配冶共。
但是有時(shí)候,這種模式不是我們想要的結(jié)果,比如最常見的HTML標(biāo)簽匹配捅僵。假設(shè)有如下的字符串:
<table>
<tr>
<td>蘋果</td>
<td>桃子</td>
<td>香蕉</td>
</tr>
</table>
我們的意圖是獲取每個(gè)<td></td>
標(biāo)簽中的元素內(nèi)容家卖,那么如果你將正則表達(dá)式寫成<td>(.*)</td>
的話,你得到的是<td>蘋果</td><td>桃子</td><td>香蕉</td>
這么個(gè)東西庙楚,而不是“蘋果”上荡、“桃子”、“香蕉”馒闷。
在修飾匹配次數(shù)的特殊符號(hào)后再加上一個(gè)?
問(wèn)號(hào)酪捡,則可以使匹配次數(shù)不定的表達(dá)式盡可能少的匹配,使可匹配可不匹配的表達(dá)式纳账,盡可能的"不匹配"逛薇。如果少匹配就會(huì)導(dǎo)致整個(gè)表達(dá)式匹配失敗的時(shí)候,與貪婪模式類似疏虫,非貪婪模式會(huì)最小限度的再多匹配一些永罚,以使整個(gè)表達(dá)式匹配成功。
表達(dá)式<td>(.*?)</td>
匹配上面的字符串時(shí)卧秘,將只得到<td>蘋果</td>
呢袱,再次匹配下一個(gè)時(shí),可以得到<td>桃子</td>
翅敌,以此類推产捞。
常用正則表達(dá)式
校驗(yàn)數(shù)字的相關(guān)表達(dá)式:
功能 | 表達(dá)式 | |
---|---|---|
數(shù)字 | ^[0-9]*$ |
|
n位的數(shù)字 | ^\d{n}$ |
|
至少n位的數(shù)字 | ^\d{n,}$ |
|
零和非零開頭的數(shù)字 | `^(0 | [1-9][0-9]*)$` |
有兩位小數(shù)的正實(shí)數(shù) | ^[0-9]+(.[0-9]{2})?$ |
|
非零的負(fù)整數(shù) | ^-[1-9]\d*$ |
|
非負(fù)浮點(diǎn)數(shù) | ^\d+(\.\d+)?$ |
|
浮點(diǎn)數(shù) | ^(-?\d+)(\.\d+)?$ |
特殊場(chǎng)景的表達(dá)式:
功能 | 表達(dá)式 |
---|---|
Email地址 | ^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$ |
域名 | [a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.? |
手機(jī)號(hào)碼 | ^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$ |
身份證號(hào) | ^\d{15}|\d{18}$(15位、18位數(shù)字) |
日期格式 | ^\d{4}-\d{1,2}-\d{1,2} |
空白行的正則表達(dá)式 |
\n\s*\r (可以用來(lái)刪除空白行) |
IP地址提取 |
\d+\.\d+\.\d+\.\d+ (提取IP地址時(shí)有用) |
騰訊QQ號(hào) |
[1-9][0-9]{4,} (騰訊QQ號(hào)從10000開始) |