Захват повторяющихся подшаблонов в регулярных выражениях Python - PullRequest
21 голосов
/ 19 марта 2012

При сопоставлении адреса электронной почты, после сопоставления с чем-то вроде yasar@webmail, я хочу захватить один или несколько из (\.\w+) (то, что я делаю, немного сложнее, это всего лишь пример), я попыталсядобавление (. \ w +) +, но захватывает только последнее совпадение.Например, yasar@webmail.something.edu.tr соответствует, но включает .tr после yasar@webmail части, поэтому я потерял группы .something и .edu.Могу ли я сделать это в регулярных выражениях Python, или вы предложите сначала сопоставить все, а потом разбить подшаблоны?

Ответы [ 4 ]

25 голосов
/ 19 марта 2012

re модуль не поддерживает повторные захваты (regex поддерживает его):

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

В вашем случае я бы пошел с разбиением повторяющихся подшаблонов позже. Это приводит к простому и читабельному коду, например, см. Код в @ Li-aung Yip's answer .

12 голосов
/ 19 марта 2012

Это будет работать:

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

Но оно ограничено максимум шестью подгруппами. Лучший способ сделать это:

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

Обратите внимание, что регулярные выражения хороши, если адреса электронной почты просты, но есть множество вещей, из-за которых это сломается. См. этот вопрос для подробной обработки регулярных выражений адресов электронной почты.

6 голосов
/ 19 марта 2012

Вы можете решить проблему (\.\w+)+, захватив только последний матч, выполнив это вместо: ((?:\.\w+)+)

3 голосов
/ 04 октября 2017

Это то, что вы ищете:

>>> import re

>>> s="yasar@webmail.something.edu.tr"
>>> r=re.compile("\.\w+")
>>> m=r.findall(s)

>>> m
['.something', '.edu', '.tr']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...