2012-03-19 102 views
16

匹配一個電子郵件地址,當我匹配[email protected]之類的東西后,我想捕獲一個或多個(\.\w+)(我正在做的是更復雜一點,這只是一個例子),我嘗試添加(。\ w +)+,但它只捕獲最後一場比賽。例如,[email protected]匹配,但只包含.tr[email protected]部分,所以我輸了.something.edu組。我可以在Python正則表達式中做到這一點,或者你會建議首先匹配所有內容,並在稍後拆分子模式?在Python正則表達式中捕獲重複子模式

回答

4

您可以修復的(\.\w+)+問題只有這樣,而不是拍攝最後一場比賽:((?:\.\w+)+)

+0

有關縮寫詞(如果你已經套管下):'應用re.sub(UR'((?:[AZ] \){2, })',lambda m:m.group(1).replace('。',''),text)' – bahmait 2015-08-15 09:58:12

+0

謝謝。我可以添加圓括號,允許我匹配一個重複的子模式,但隨後有一個組與最後一個模式匹配。我沒有看到'(?:...)'是一個非捕獲組。 https://docs.python.org/2/library/re.html#regular-expression-syntax添加修復該問題。 – 2016-07-21 22:22:11

11

這將工作:

>>> regexp = r"[\w\.][email protected](\w+)(\.\w+)?(\.\w+)?(\.\w+)?(\.\w+)?(\.\w+)?" 
>>> email_address = "[email protected]" 
>>> m = re.match(regexp, email_address) 
>>> m.groups() 
('galactica', '.caprica', '.fleet', '.mil', None, None) 

但它僅限於一個最大的6輛編組。一個更好的辦法來做到這一點是:

>>> m = re.match(r"[\w\.][email protected](.+)", email_address) 
>>> m.groups() 
('galactica.caprica.fleet.mil',) 
>>> m.group(1).split('.') 
['galactica', 'caprica', 'fleet', 'mil'] 

注意,正則表達式的罰款,只要電子郵件地址很簡單 - 但也有各種各樣的東西,這將打破。有關電子郵件地址正則表達式的詳細處理,請參見this question

19

re模塊不支持重複捕獲(regex支持的話):

>>> m = regex.match(r'([.\w]+)@((\w+)(\.\w+)+)', '[email protected]') 
>>> m.groups() 
('yasar', 'webmail.something.edu.tr', 'webmail', '.tr') 
>>> m.captures(4) 
['.something', '.edu', '.tr'] 

在你的情況我會去與後來的分裂重複子模式。它導致一個簡單易讀的代碼,例如,參見@Li-aung Yip's answer中的代碼。

+0

出於好奇,當你匹配重複捕捉時,你如何編寫替換模式? 「\ 1」,「\ 2」,「3」等的含義是否根據您匹配的次數(\。\ w +)而改變? – 2012-03-19 07:55:39

+0

@ Li-aung Yip:'\ 1'對應'm.group(1)';意義沒有改變。你可以使用一個函數作爲替換模式,並在其中調用m.captures()。 – jfs 2012-03-19 09:03:02

+0

在你的例子中,'\ 1','\ 2'和'\ 3'的含義很明顯,因爲它們只捕獲一次。但'\ 4'的含義是什麼,對應於(\。\ w +)+'? '\ 4'看起來是「第四個捕獲組匹配的最後一個子字符串」,在這種情況下是'.tr'。 – 2012-03-19 09:12:14

1

這是你在找什麼:

>>> import re 

>>> s="[email protected]" 
>>> r=re.compile("\.\w+") 
>>> m=r.findall(s) 

>>> m 
['.something', '.edu', '.tr']