1. 程式人生 > >Python中正則匹配使用findall時的註意事項

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

使用 earch 寫法 為什麽 tps 功能 str span port

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

比如說有一個字符串 "[email protected]@[email protected]@asdfcom"

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

寫了個正則,測試一下:

>>> import re
>>> s  = "[email protected]@[email protected]@asdfcom"
>>> pattern1 = "\w+@(qq|163|126)\.com"
>>> m1 = re.search(pattern1,s)
>>> m1.group()
‘[email protected]

可以看到,能夠正確搜索到第一個結果,正則寫得沒問題,如果我想得到所有結果,自然而然就想到了用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
[‘[email protected]‘, ‘[email protected]‘, ‘[email protected]‘]

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

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

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

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

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

>>> 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

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