正則表達式中斷言的使用以及簡單例子

原文鏈接:
https://www.cnblogs.com/dogecheng/p/11466687.html
https://www.cnblogs.com/he-qing-qing/p/11331080.html
版權聲明:本文爲轉載文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。

正則表達式斷言

概念

零寬斷言

  • 匹配寬度爲零,滿足一定的條件/斷言。
  • 零寬斷言用於查找在某些內容(但並不包括這些內容)之前或之後的東西,也就是說它們像\b,^,$那樣用於指定一個位置,這個位置應該滿足一定的條件(即斷言),因此它們也被稱爲零寬斷言。
  • 斷言用來聲明一個應該爲真的事實。正則表達式中只有當斷言爲真時纔會繼續進行匹配

零寬斷言分四種

先行斷言(零寬度正預測先行斷言)

  • 表達式:(?=表達式)
  • 表示匹配表達式前面的位置
  • 先行斷言的執行步驟是這樣的先從要匹配的字符串中的最右端找到第一個ing(也就是先行斷言中的表達式)然後 再匹配其前面的表達式,若無法匹配則繼續查找第二個ing 再匹配第二個 ing前面的字符串,若能匹配 則匹配
  • .*(?=d) 可c以匹配abcdefghi 中的abc

後發斷言(零寬度正回顧後發斷言)

  • 表達式: (?<=表達式)
  • 表示匹配表達式後面的位置
  • 後發斷言跟先行斷言恰恰相反 它的執行步驟是這樣的:先從要匹配的字符串中的最左端找到第一個abc(也就是先行斷言中的表達式)然後 再匹配其後面的表達式,若無法匹配則繼續查找第二個abc 再匹配第二個abc後面的字符串,若能匹配 則匹配
  • 例如(?<=abc).* 可以匹配abcdefg中的defg

負向斷言

  • 負向零寬先行斷言 :(?!表達式)
  • 負向零寬後發斷言:(?<!表達式)
  • 負向零寬斷言 (?!表達式) 也是匹配一個零寬度的位置,不過這個位置的“斷言”取表達式的反值,例如 (?!表達式) 表示 表達式 前面的位置,如果 表達式 不成立 ,匹配這個位置;如果 表達式 成立,則不匹配:同樣,負向零寬斷言也有“先行”和“後發”兩種,負向零寬後發斷言爲 (?<!表達式)

例子

(?:pattern)

()表示捕獲分組,()會把每個分組裏的匹配的值保存起來,從左向右,以分組的左括號爲標誌,第一個出現的分組的組號爲1,第二個爲2,以此類推

(?:)表示非捕獲分組,和捕獲分組唯一的區別在於,非捕獲分組匹配的值不會保存起來

import re
a = "123abc456"
pattern = "([0-9]*)([a-z]*)([0-9]*)"
print(re.search(pattern,a).group(0,1,2,3))

pattern = "(?:[0-9]*)([a-z]*)([0-9]*)"
print(re.search(pattern,a).group(0,1,2))

在這裏插入圖片描述
可以看到使用 (?:pattern) 後匹配的第一個 [0-9] 沒有保存下來。python中group(0)返回整體。

(?:pattern)匹配 pattern 但不獲取匹配結果,也就是說這是一個非獲取匹配,不進行存儲供以後使用。
正則表達式的匹配原理可以參考這篇文章:

https://blog.csdn.net/lxcnn/article/details/4304651

這在使用 “或” 字符 (|) 來組合一個模式的各個部分是很有用。例如, 'industr(?:y|ies) 就是一個比 ‘industry|industries’ 更簡略的表達式。

(?=pattern)

正向肯定預查(look ahead positive assert),匹配pattern前面的位置。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以後使用。

簡單說,以 xxx(?=pattern)爲例,就是捕獲以pattern結尾的內容xxx

例如,“Windows(?=95|98|NT|2000)“能匹配"Windows2000"中的"Windows”,但不能匹配"Windows3.1"中的"Windows”。預查不消耗字符,也就是說,在一個匹配發生後,在最後一次匹配之後立即開始下一次匹配的搜索,而不是從包含預查的字符之後開始。

(?=pattern)和(?:pattern)的區別可以參考:https://blog.csdn.net/shashagcsdn/article/details/80017678

(?!pattern)

正向否定預查(negative assert),在任何不匹配pattern的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以後使用。

簡單說,以 xxx(?!pattern)爲例,就是捕獲不以pattern結尾的內容xxx

例如"Windows(?!95|98|NT|2000)“能匹配"Windows3.1"中的"Windows”,但不能匹配"Windows2000"中的"Windows"。預查不消耗字符,也就是說,在一個匹配發生後,在最後一次匹配之後立即開始下一次匹配的搜索,而不是從包含預查的字符之後開始。

(?<=pattern)

反向(look behind)肯定預查,與正向肯定預查類似,只是方向相反。

簡單說,以(?<=pattern)xxx爲例,就是捕獲以pattern開頭的內容xxx。

例如,"(?<=95|98|NT|2000)Windows"能匹配"2000Windows"中的"Windows",但不能匹配"3.1Windows"中的"Windows"。

(?<!pattern)

簡單說,以(?<!pattern)xxx爲例,就是捕獲不以pattern開頭的內容xxx。

反向否定預查,與正向否定預查類似,只是方向相反。例如"(?<!95|98|NT|2000)Windows"能匹配"3.1Windows"中的"Windows",但不能匹配"2000Windows"中的"Windows"。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章