一、零寬斷言
此篇文章為python正則表達式的高階入門,正則基礎入門請參考程式設計師入門基礎:python的正則表達式。
斷言也可以理解為判斷的意思,正則表達式中有很多這樣的斷言,常見的如 ^ 和 /A,匹配字符串或者行的末尾 $ 和 /Z,單詞邊界/B等等。
零寬斷言是並不去真正的匹配字符串文本,而僅僅是匹配對應的位置,斷言本身並不匹配,因為匹配的寬度為零,故零寬。當然零寬斷言還有各種叫法,如環視、預搜索等。
常見的零寬斷言有四種形式,即正向肯定,正向否定,負向肯定,負向否定。
二、正向肯定
格式:(?=exp),正向(向右)匹配位置,但不計入結果
import re
#(?=dog)位置開始匹配,但不計入匹配結果
print("匹配開始位置dog:",re.search(r'(?=dog)dogeat',"dogeat@homework"))
#dog(?=eat)位置開始匹配,但(?=eat)不計入匹配結果
print("匹配開始位置eat:",re.search(r'dog(?=eat)eat',"dogeat@homework"))
#注意dog(?=homework)實際等於doghomework與原字符串不同,不可匹配
print("匹配開始位置homework:",re.search(r'dog(?=homework)@homework',"dogeat@homework"))
開始位置dog: <re.Match object; span=(0, 6), match='dogeat'>
開始位置eat: <re.Match object; span=(0, 6), match='dogeat'>
開始位置homework: None
三、正向否定
格式:(?!exp),正向(向右)否定匹配位置,但不計入結果
import re#
#@homework位置開始匹配,無aa,匹配成功
print("(?!aa)@homework:",re.search(r'(?!eat)@homework',"dogeat@homework"))
#dog位置開始匹配,後續無cat,匹配成功
print("dog(?!cat)eat:",re.search(r'dog(?!cat)eat',"dogeat@homework"))
#dog位置開始匹配,後續無eat,匹配失敗
print("dog(?!eat)@homework:",re.search(r'dog(?!eat)eat@homework',"dogeat@homework"))
(?!aa)@homework: <re.Match object; span=(6, 15), match='@homework'>
dog(?!cat)eat: <re.Match object; span=(0, 6), match='dogeat'>
dog(?!eat)@homework: None
四、負向肯定
格式:(?<=exp),負向(向左)匹配位置,但不計入結果。
特別注意,如遇負向零寬斷言(包括負向肯定與否定),正則驗證的順序為,先跳過斷言後,再從右向左驗證,即負向驗證。
import re##
#@homework位置開始向左匹配,匹配成功
print("(?<=eat)@homework:",re.search(r'(?<=eat)@homework',"dogeat@homework"))
#eat位置開始向左匹配,匹配成功
print("dog(?<=dog)eat:",re.search(r'dog(?<=dog)eat',"dogeat@homework"))
#eat@homework位置開始匹配,左側無eat,匹配失敗,應該為dog
print("dog(?<=eat)eat@homework:",re.search(r'dog(?<=eat)eat@homework',"dogeat@homework"))
(?<=eat)@homework: <re.Match object; span=(6, 15), match='@homework'>
dog(?<=dog)eat: <re.Match object; span=(0, 6), match='dogeat'>
dog(?<=eat)eat@homework: None
五、負向否定
格式:(?<!exp),負向(向左)否定匹配位置,但不計入結果。
import re###
#@homework位置開始向左匹配,匹配失敗
print("(?<!eat)@homework:",re.search(r'(?<!eat)@homework',"dogeat@homework"))
#eat位置開始向左匹配,匹配失敗
print("dog(?<!dog)eat:",re.search(r'dog(?<!dog)eat',"dogeat@homework"))
#eat@homework位置開始匹配,左側無eat,匹配成功,失敗時為dog
print("dog(?<!eat)eat@homework:",re.search(r'dog(?<!eat)eat@homework',"dogeat@homework"))
(?<!eat)@homework: None
dog(?<!dog)eat: None
dog(?<!eat)eat@homework: <re.Match object; span=(0, 15), match='dogeat@homework'>
六、總結
學習正則表達式,有些瑣碎,一定要多練習,有些東西記住後過一段時間就忘了,很正常。就像把這些知識存儲在硬碟裡,只要能做到快速調入內存(大腦)即可。