正則表達式的匹配原理可以參考這篇文章:https://blog.csdn.net/lxcnn/article/details/4304651
(?:pattern)
()表示捕獲分組,()會把每個分組里的匹配的值保存起來,從左向右,以分組的左括號為標志,第一個出現的分組的組號為1,第二個為2,以此類推
(?:)表示非捕獲分組,和捕獲分組唯一的區別在於,非捕獲分組匹配的值不會保存起來
import re a = "123abc456ww" 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))
可以看到 (?:[0-9]*) 匹配的第一個 [0-9]* 沒有保存下來,即沒有保存匹配到的“123”,而([0-9]*)則保存了下來。
python中group(0)返回匹配到的整體
(?:pattern)在使用 "或" 字符 (|) 來組合一個模式的各個部分是很有用。例如,'industr(?:y|ies)' 就是一個比 'industry|industries' 更簡略的表達式。因為我們單獨存儲下 “y” 或者 “ies” 沒有什么意義
a = "British industry" pattern = "industr(?:y|ies)" print(re.search(pattern,a).group(0)) # group(1)會報錯,因為沒有保存捕獲到的“y” pattern = "industr(y|ies)" print(re.search(pattern,a).group(0, 1))
(?=pattern)
正向肯定預查(look ahead positive assert),匹配pattern前面的位置。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以后使用。
簡單說,以 xxx(?=pattern)為例,就是捕獲以pattern結尾的內容xxx
例如,"Windows(?=95|98|NT|2000)"能匹配"Windows2000"中的"Windows",但不能匹配"Windows3.1"中的"Windows"。預查不消耗字符,也就是說,在一個匹配發生后,在最后一次匹配之后立即開始下一次匹配的搜索,而不是從包含預查的字符之后開始。
(?!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
"。
參考資料
https://deerchao.net/tutorials/regex/regex.htm
https://www.runoob.com/regexp/regexp-metachar.html
https://blog.csdn.net/lxcnn/article/details/4304651
https://blog.csdn.net/shashagcsdn/article/details/80017678