2012-03-19 29 views
16

Khi kết hợp địa chỉ email, sau khi tôi khớp một thứ như [email protected], tôi muốn chụp một hoặc nhiều (\.\w+) (những gì tôi đang làm là phức tạp hơn một chút, đây chỉ là một ví dụ), Tôi đã thử thêm (. \ W +) +, nhưng nó chỉ ghi lại kết quả cuối cùng. Ví dụ: [email protected] đối sánh nhưng chỉ bao gồm .tr sau [email protected] một phần, vì vậy tôi đã mất .something.edu nhóm. Tôi có thể làm điều này trong các biểu thức chính quy của Python hay bạn sẽ đề xuất kết hợp mọi thứ lúc đầu và chia nhỏ các mẫu con sau?Chụp các mẫu phụ lặp lại trong Python regex

Trả lời

4

Bạn có thể khắc phục vấn đề của (\.\w+)+ chỉ chụp trận đấu cuối cùng bằng cách làm này để thay thế: ((?:\.\w+)+)

+0

Đối với chữ viết tắt (nếu bạn đã thấp-cased): 're.sub (ur '((:?. [Az] \) {2, }) ', lambda m: m.group (1) .replace ('. ',' '), văn bản) ' – bahmait

+0

Cảm ơn. Tôi đã có thể thêm dấu ngoặc đơn cho phép tôi đối sánh với một mẫu con lặp lại, nhưng sau đó có một nhóm trong kết hợp với mẫu cuối cùng của mẫu. Tôi đã không thấy rằng '(?: ...)' làm cho một nhóm không bắt. https://docs.python.org/2/library/re.html#regular-expression-syntax Thêm rằng khắc phục sự cố đó. –

11

này sẽ làm việc:

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

Nhưng đó là giới hạn tối đa là sáu nhóm nhỏ. Cách tốt hơn để thực hiện việc này là:

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

Lưu ý rằng regexps là tốt miễn là địa chỉ email đơn giản - nhưng có tất cả những thứ mà điều này sẽ phá vỡ. Xem this question để biết cách xử lý chi tiết các regex địa chỉ email.

19

re mô-đun không hỗ trợ chụp lặp đi lặp lại (regex hỗ trợ nó):

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

Trong trường hợp của bạn tôi muốn đi với tách subpatterns lặp đi lặp lại sau đó. Nó dẫn đến một mã đơn giản và dễ đọc, ví dụ: xem mã trong số @Li-aung Yip's answer.

+0

Ngoài sự tò mò, làm thế nào để bạn viết một mẫu thay thế khi bạn kết hợp các lần chụp lặp lại? Ý nghĩa của '\ 1',' \ 2', '\ 3' vv có thay đổi tùy thuộc vào số lần bạn so khớp' (\. \ W +) 'không? –

+0

@ Li-aung Yip: '\ 1' tương ứng với' m.group (1) '; ý nghĩa đã không thay đổi. Bạn có thể sử dụng một hàm như là một mẫu thay thế và gọi 'm.captures()' trong đó. – jfs

+0

Trong ví dụ của bạn, ý nghĩa của '\ 1',' \ 2' và '\ 3' là hiển nhiên bởi vì chúng chỉ chụp một lần. Nhưng ý nghĩa của '\ 4', tương ứng với' (\. \ W +) + 'là gì? '\ 4' dường như là" chuỗi con cuối cùng được so khớp bởi nhóm chụp thứ 4 ", trong trường hợp này là' .tr'. –

1

Đây là những gì bạn đang tìm kiếm:

>>> import re 

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

>>> m 
['.something', '.edu', '.tr'] 
Các vấn đề liên quan