Python Regex: cómo obtener posiciones y valores de coincidencias

112

¿Cómo puedo obtener las posiciones inicial y final de todos los partidos usando el remódulo? Por ejemplo, dado el patrón r'[a-z]'y la cadena, 'a1b2c3d4'me gustaría obtener las posiciones donde encuentra cada letra. Idealmente, también me gustaría recuperar el texto de la coincidencia.

Greg
fuente
Vea si esto ayuda a Match Objects
EBGreen

Respuestas:

140
import re
p = re.compile("[a-z]")
for m in p.finditer('a1b2c3d4'):
    print(m.start(), m.group())
Peter Hoffmann
fuente
3
Esto no proporciona un índice de otros grupos en una coincidencia regex = r '([az]) (0-9)' m.start será para el grupo (), no para el grupo (1)
StevenWernerCS
@StevenWernerCS start()puede aceptar un número de grupo, por lo que si desea un índice del grupo n, usestart(n)
Hi-Angel
@ hi-angel sí, mira mi respuesta a continuación del año pasado que hace precisamente eso
StevenWernerCS
51

Tomado de

CÓMO de expresiones regulares

span () devuelve los índices inicial y final en una única tupla. Dado que el método de coincidencia solo comprueba si el RE coincide al comienzo de una cadena, start () siempre será cero. Sin embargo, el método de búsqueda de las instancias de RegexObject escanea la cadena, por lo que es posible que la coincidencia no comience en cero en ese caso.

>>> p = re.compile('[a-z]+')
>>> print p.match('::: message')
None
>>> m = p.search('::: message') ; print m
<re.MatchObject instance at 80c9650>
>>> m.group()
'message'
>>> m.span()
(4, 11)

Combina eso con:

En Python 2.2, el método finditer () también está disponible y devuelve una secuencia de instancias de MatchObject como iterador.

>>> p = re.compile( ... )
>>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
>>> iterator
<callable-iterator object at 0x401833ac>
>>> for match in iterator:
...     print match.span()
...
(0, 2)
(22, 24)
(29, 31)

deberías poder hacer algo del orden de

for match in re.finditer(r'[a-z]', 'a1b2c3d4'):
   print match.span()
ido
fuente
Puede usarlo como re.search(r'abbit', "has abbit of carrot").span(0)-(4, 9)
Константин Ван
El 'índice final' devuelto por span()es como el 'stop' en la notación de segmento de Python en el sentido de que sube pero no incluye ese índice; ver aquí .
Wayne
20

Para Python 3.x

from re import finditer
for match in finditer("pattern", "string"):
    print(match.span(), match.group())

Obtendrá \ntuplas separadas (que comprenden el primer y último índice de la coincidencia, respectivamente) y la coincidencia en sí, para cada hit de la cadena.

Rams Here
fuente
2

tenga en cuenta que el intervalo y el grupo están indexados para grupos de captura múltiple en una expresión regular

regex_with_3_groups=r"([a-z])([0-9]+)([A-Z])"
for match in re.finditer(regex_with_3_groups, string):
    for idx in range(0, 4):
        print(match.span(idx), match.group(idx))
StevenWernerCS
fuente
1
Gracias, esto ha resultado muy útil y parece estar bastante enterrado. Además, en caso de que alguien necesite esto: cuando se usan grupos de captura con nombre, se puede encontrar el índice de un grupo usando <match> .re.groupindex, y desde allí encontrar el intervalo correspondiente usando el enfoque que describió
madimov
de donde 4viene el
Radio controlado
@RadioControlled number_of_known_groups_in_the_regex + 1, ya que el rango es [inicio, fin) exclusivo del final
StevenWernerCS
@StevenWernerCS para que no se generalice a los casos en los que se desconoce el número de grupos ...
Radio controlado