2011-04-08 16 views
8

Pregunta de expresiones regulares rápidas.
Estoy tratando de capturar varias instancias de un grupo de captura en python (no creo que sea específico de Python), pero las capturas posteriores parecen sobrescribir las anteriores.Captura de grupos de expresiones regulares con múltiples coincidencias

En este ejemplo exceso de simplificación, estoy esencialmente tratando de dividir una cadena:

x = 'abcdef' 
r = re.compile('(\w){6}') 
m = r.match(x) 
m.groups()  # = ('f',) ?!? 
quiero conseguir ('a', 'b', 'c', 'd', 'e', 'f'), pero debido a la expresión regular sobrescribe capturas posteriores, me sale ('f',)

¿Es así como ¿Se supone que Regex se comporta? ¿Hay alguna manera de hacer lo que quiero sin tener que repetir la sintaxis seis veces?

¡Gracias de antemano!
Andrew

+1

No lo creo. Hay re.findall y re.split para estos problemas. –

+0

posible duplicado de [grupos múltiples de Pyge regex] (http://stackoverflow.com/questions/4963691/python-regex-multiple-groups) – outis

+1

Aquí hay un buen artículo acerca de la captura de un grupo repetido. http://www.regular-expressions.info/captureall.html Ejemplo:! Abcabc123! Para la captura, ¡todos los abc y 123 necesitan expresiones regulares! ((? :(abc) | (123)) +) !. Tenga en cuenta los corchetes adicionales. – b0bi

Respuesta

13

No se pueden usar grupos para esto, me temo. Cada grupo puede coincidir solo una vez, creo que todas las expresiones regulares funcionan de esta manera. Una posible solución es tratar de usar findall() o similar.

r=re.compile(r'\w') 
r.findall(x) 
# 'a', 'b', 'c', 'd', 'e', 'f' 
+1

bawk! * patadas pueden * ¿Por qué no puede hacer exactamente lo que quiero como quiero! --¡Gracias! Andrew –

+0

He estado buscando el comando mientras navego por 're.search'' re.match' y el 're.MatchObject' devuelto – Sevenearths

2

Para encontrar todas las coincidencias en una cadena dada, use re.findall(regex, string). Además, si desea obtener todas las letras aquí, su expresión regular debe ser '(\w){1}' o simplemente '(\w)'.

Ver:

r = re.compile('(\w)') 
l = re.findall(r, x) 

l == ['a', 'b', 'c', 'd', 'e', 'f'] 
1

supongo que tu pregunta es una presentación simplificada de su necesidad.

Entonces, tomo un exemple un poco más complejo:

import re 

pat = re.compile('[UI][bd][ae]') 

ch = 'UbaUdeIbaIbeIdaIdeUdeUdaUdeUbeIda' 

print [mat.group() for mat in pat.finditer(ch)] 

resultado

['Uba', 'Ude', 'Iba', 'Ibe', 'Ida', 'Ide', 'Ude', 'Uda', 'Ude', 'Ube', 'Ida'] 
4

El módulo regex puede hacer esto.

> m = regex.match('(\w){6}', "abcdef") 
> m.captures(1) 
['a', 'b', 'c', 'd', 'e', 'f'] 

También funciona con capturas con nombre: se espera

> m = regex.match('(?P<letter>)\w)', "abcdef") 
> m.capturesdict() 
{'letter': ['a', 'b', 'c', 'd', 'e', 'f']} 

El módulo de expresiones regulares para reemplazar el módulo 're' - es una gota en el reemplazo que actúa de forma idéntica, excepto que tiene muchas más funciones y capacidades.

Cuestiones relacionadas