2012-03-19 15 views
16

Al hacer coincidir una dirección de correo electrónico, después de que coincida con algo como [email protected], quiero capturar uno o más de (\.\w+) (lo que estoy haciendo es un poco más complicado, esto es solo un ejemplo), Intenté agregar (. \ W +) +, pero solo captura el último partido. Por ejemplo, [email protected] coincide pero solo incluye .tr después de [email protected] parte, por lo que perdí .something y .edu grupos. ¿Puedo hacer esto en expresiones regulares de Python, o sugeriría que coincida con todo al principio, y dividiría los subpatrones más tarde?Captura de subpatterns repetitivos en Python regex

Respuesta

4

Puede solucionar el problema de la captura de (\.\w+)+ solamente el último partido al hacer esto en su lugar: ((?:\.\w+)+)

+0

Para las abreviaturas (si has entubados inferior): 're.sub (ur '((:?. [Az] \) {2, }) ', lambda m: m.group (1) .replace ('. ',' '), text) ' – bahmait

+0

Gracias. Pude agregar los paréntesis que me permitían hacer coincidir un subpatrón repetido, pero luego había un grupo en el partido con el último del patrón. No había visto que '(?: ...)' hace un grupo que no captura. https://docs.python.org/2/library/re.html#regular-expression-syntax Agregando que corrige ese problema. –

11

esto funcionará:

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

Pero es limitada a un máximo de seis subgrupos. Una mejor manera de hacer esto sería:

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

Tenga en cuenta que las expresiones regulares son bien siempre y cuando las direcciones de correo electrónico son simples - pero hay todo tipo de cosas que este se romperá para. Ver this question para un tratamiento detallado de expresiones regulares de dirección de correo electrónico.

módulo
19

re no soporta capturas repetidas (regex lo soporta):

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

En su caso me gustaría ir con la división de los sub-patrones repetidos después. Conduce a un código simple y legible, por ejemplo, vea el código en @Li-aung Yip's answer.

+0

Por curiosidad, ¿cómo se escribe un patrón de reemplazo cuando se combinan las capturas repetidas? ¿El significado de '\ 1',' \ 2', '\ 3' etc. cambia dependiendo de cuántas veces coincide' (\. \ W +) '? –

+0

@ Li-aung Yip: '\ 1' corresponde a' m.group (1) '; el significado no ha cambiado Puede usar una función como patrón de reemplazo y llamar 'm.captures()' en ella. – jfs

+0

En su ejemplo, el significado de '\ 1',' \ 2' y '\ 3' es obvio porque solo capturan una vez. ¿Pero cuál es el significado de '\ 4', que corresponde a' (\. \ W +) + '? '\ 4' parece ser" la última subcadena que coincide con el 4º grupo de captura ", en este caso' .tr'. –

1

esto es lo que están buscando:

>>> import re 

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

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