
轉(zhuǎn)載請注明出處:http://www.itdecent.cn/p/ebba0458d889
本文出自 容華謝后的博客
往期回顧:
0.寫在前面
一提到斷言,很多人第一時間就會想到單元測試,在正則中,斷言是指對匹配到的文本位置有要求,比如我們想要查找一段文本中 tom 這個單詞,但是其他單詞 tomorrow 或者 tomato 也包含 tom,我們該怎么去限定呢,這就是斷言大顯身手的時候了。
對匹配到的文本位置有要求,其實就是限定單詞左邊和右邊的字符類型,細想下來,其實和單元測試中的斷言也差不多,正則中常見的斷言有三種,分別是單詞邊界、行的開始和結束、環(huán)視,一起來看下。
1.單詞邊界
我們在第三篇文章中,學習了正則中分組與引用的知識,其中在查找那一節(jié),我們舉了一個例子,來回顧下:
有這樣一個需求,在一個目標字符串中,查找兩個重復出現(xiàn)的單詞,還沒有學到單詞邊界,我們先用 \w{2,} 來表示出現(xiàn)的單詞,重復的單詞就是 (\w{2,} \1),看下結果:

有的同學會有疑問,為什么要用 \w{2,} 來表示一個單詞呢,\w+ 不行嗎,來看下 \w+ 匹配的效果:

可以看到字母 s 也被匹配到了,這并不是我們想要的結果,我們需要優(yōu)雅的解決這個問題,就用到了單詞邊界,邊界的英文是 Boundary,取其首字母小寫,就用 \b 來表示,可以寫在單詞的左邊或右邊,修改之后是這樣的:

\b 放在單詞的左邊或者右邊,匹配結果是不一樣的:
| 單詞 | tom 單詞包含 tom |
\btom 以 tom 開頭的單詞 |
tom\b 以 tom 結尾的單詞 |
\btom\b 只能是 tom |
|---|---|---|---|---|
| tom | ? | ? | ? | ? |
| tomorrow | ? | ? | ? | ? |
| atom | ? | ? | ? | ? |
| atomic | ? | ? | ? | ? |
2.行的開始和結束
在前幾篇文章中,我們已經(jīng)對行的開始和結束標記有一些了解了,在正則中,我們使用脫字符 ^ 來表示行的開始,美元符 $ 來表示行的結尾,舉個栗子:
對登錄密碼進行格式校驗,密碼要求是6位連續(xù)的數(shù)字,我們可以很快的寫出正則表達式 \d{6},來驗證下:

可以看到6位數(shù)字可以匹配成功,7位、8位也可以匹配成功,這顯然是不對的,修改下:

和單詞邊界差不多,^ 限定以什么開始,$ 限定以什么結尾,只不過限定的不是單詞,而是一段文本。
我們還可以使用 \A 和 \z(Python 中使用 \Z) 來限定行的開始和結束:

注意:\A \Z 這種匹配方式是不支持多行模式的,目標字符串中也不可以有其他字符,比如換行或者空格。
3.環(huán)視
環(huán)視在正則中的意思就是左右看,也被稱為零寬斷言,和單詞邊界類似,但是更加靈活了,環(huán)視可以限定單詞的左邊可以是什么類型,不可以是什么類型,單詞的右邊可以是什么類型,不可以是什么類型:
| 正則 | 名稱 | 含義 | 示例 |
|---|---|---|---|
| (?<=Y) | 肯定逆序環(huán)視 | 左邊是Y | (?<=\d)th 左邊是數(shù)字的 th,可以匹配上 9th |
| (?<!Y) | 否定逆序環(huán)視 | 左邊不是Y | (?<!\d)th 左邊不是數(shù)字的 th,可以匹配上 health |
| (?=Y) | 肯定順序環(huán)視 | 右邊是Y | six(?=\d) 右邊是數(shù)字的 six,可以匹配上 six6 |
| (?!Y) | 否定順序環(huán)視 | 右邊不是Y | six(?!\d) 右邊不是數(shù)字的 six,可以匹配上 sixgod |
環(huán)視的正則表達式是用括號括起來的,注意這個括號不會被保存成子組,引用數(shù)括號位置的時候注意跳過。
這四個表達式,乍一看起來有點懵,其實是有規(guī)律可循的,帶尖括號的看左邊,不帶尖括號的看右邊,帶嘆號就是否定,這樣就好記了。
我們用環(huán)視來表示下上面學到的單詞邊界,可以這樣寫 ((?<!\w)\w+(?!\w)):

4.寫在最后
最后在總結下上面講到的內(nèi)容:

到這里,正則表達式的斷言匹配就講完了,如果有問題可以給我留言評論,謝謝。
正則表達式在線校驗工具:https://regex101.com/