Python中正則匹配使用findall時的注意事項


在使用正則搜索內容時遇到一個小坑,百度搜了一下,遇到這個坑的還不少,特此記錄一下。

比如說有一個字符串  "123@qq.comaaa@163.combbb@126.comasdf111@asdfcom"

想匹配出里面所有的郵箱地址,該怎么實現呢?

寫了個正則,測試一下:

>>> import re
>>> s  = "123@qq.comaaa@163.combbb@126.comasdf111@asdfcom"
>>> pattern1 = "\w+@(qq|163|126)\.com"
>>> m1 = re.search(pattern1,s)
>>> m1.group()
'123@qq.com'

 可以看到,能夠正確搜索到第一個結果,正則寫得沒問題,如果我想得到所有結果,自然而然就想到了用findall()方法。來試試看:

>>> m2 = re.findall(pattern1,s)
>>> m2
['qq', '163', '126']

 這時候估計很多人就覺得奇怪了,使用search方法能搜索到,說明正則寫得沒問題呀,為什么使用findall的時候結果是這個樣子的?為什么結果不是整個郵箱字符串?

查了資料才清楚一個概念,叫做捕獲分組

簡單說,就是正則表示式里出現括號的時候,括號里的內容匹配到的部分是會被作為結果輸出的,而不是把整個正則表達式匹配到的內容作為結果輸出。

所以,就出現了上面的結果了。

那怎么得到想要的結果呢?在Python里,當一個分組的頭部出現"?:"時,表示這是一個非捕獲分組,意思就是它只是正常參與匹配過程,但不作為獨立的結果進行輸出。

那么按這個寫法來試試:

>>> pattern2 = "\w+@(?:qq|163|126)\.com"
>>> m2 = re.findall(pattern2,s)
>>> m2
['123@qq.com', 'aaa@163.com', 'bbb@126.com']

 取消了這個捕獲分組,那么就是把整個表達式作為一個結果輸出,這樣才是我們預期想要的效果。

這種情況在使用正則中的“或”匹配時是特別需要注意的,因為這時候通常會加括號,很多初學者很容易掉進這個坑,得到一個不知所謂的結果。

當然,捕獲分組這個功能本來是正常有用的,只是要用對了才行。

比如,同樣是剛才這個例子,如果只想要郵箱中的用戶名部分,該怎么寫正則表達式呢?

顯然就是把用戶名部分加括號作為一個捕獲分組就可以了。

>>> pattern3 = "(\w+)@(?:qq|163|126)\.com"
>>> m3 = re.findall(pattern3,s)
>>> m3
['123', 'aaa', 'bbb']

 

對於findall()函數,其幫助是這么說明的:

findall函數,就是說在正則匹配里,如果有分組,就僅僅匹配分組里面的內容,然后返回這個組的列表; 如果有多個分組,那就把每一個分組看成一個單位,組合為一個元組,然后返回一個含有多個元組的列表。

分組這個功能還是比較強大的,以后會繼續學習更多的部分。

 

參考文章:https://blog.csdn.net/qq_42739440/article/details/81117919


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM