2010-10-09 13 views
42

Estoy usando la función de búsqueda en el módulo re para hacer coincidir algunas cosas y todo está funcionando.Número de coincidencias de expresiones regulares

Ahora necesito saber cuántas coincidencias tengo, ¿es posible sin recorrer el iterador dos veces? (Uno para averiguar el recuento y luego la iteración real)

Editar: a lo solicitado, algo de código:

imageMatches = re.finditer("<img src\=\"(?P<path>[-/\w\.]+)\"", response[2]) 
<Here I need to get the number of matches> 
for imageMatch in imageMatches: 
    doStuff 

Todo funciona, sólo necesito para obtener el número de coincidencias antes del bucle.

Respuesta

61

Si sabes que querrás todas las coincidencias, puedes usar la función re.findall. Devolverá una lista de todas las coincidencias. Luego puede hacer len(result) para la cantidad de coincidencias.

+5

@Rafe Kettler: findall no se solapa. De la documentación: devuelve todas las coincidencias de patrón no superpuestas en cadena, como una lista de cadenas. La cadena se escanea de izquierda a derecha y las coincidencias se devuelven en el orden en que se encuentran. – JoshD

+0

@Rafe Kettler & JoshD: Gracias por la aclaración, las piezas nunca se superpondrán, así que eso no será un problema para mí en este caso. La única molestia con re.findall es que pierdo mis grupos nombrados, pero funciona así que es lo suficientemente bueno. – dutt

+0

De acuerdo, publiqué mi respuesta de todos modos. Rastros felices. –

7

Si siempre necesita saber la longitud, y solo necesita el contenido de la coincidencia en lugar de la otra información, también puede usar re.findall. De lo contrario, si solo necesita la longitud a veces, puede usar, p.

matches = re.finditer(...) 
... 
matches = tuple(matches) 

para almacenar la iteración de las coincidencias en una tupla reutilizable. Entonces solo haz len(matches).

Otra opción, si usted sólo necesita saber el recuento total después de hacer cualquier cosa con los objetos de los partidos, es utilizar

matches = enumerate(re.finditer(...)) 

que devolverá un par (index, match) para cada uno de los partidos originales. Entonces puedes simplemente almacenar el primer elemento de cada tupla en alguna variable.

Pero si usted necesita la longitud en primer lugar, y lo que necesita coincidir con los objetos en lugar de sólo las cuerdas, sólo debe hacer

matches = tuple(re.finditer(...)) 
4

Si usted encuentra que necesita para seguir con finditer(), sólo tiene que usa un contador mientras iteras a través del iterador.

Ejemplo:

>>> from re import * 
>>> pattern = compile(r'.ython') 
>>> string = 'i like python jython and dython (whatever that is)' 
>>> iterator = finditer(pattern, string) 
>>> count = 0 
>>> for match in iterator: 
     count +=1 
>>> count 
3 

Si necesita las características de finditer() (no emparejan a los casos superpuestos), utilizar este método.

+0

Sí, pensé en hacer eso, pero debido a cosas en mi código "doStuff" no funcionará sin agregar muchos códigos adicionales en varios lugares. Gracias por el consejo de todos modos :) – dutt

+0

Yo usaría 'para count, match en enumerate (iterator):' en el caso del código de Rafe. –

+0

@Tony: gracias, se olvidó de enumerar. Sin embargo, si usa enumerar, le dará el mayor * índice *, no el número real de coincidencias; para eso, tendría que agregar 1. –

4
#An example for counting matched groups 
import re 

pattern = re.compile(r'(\w+).(\d+).(\w+).(\w+)', re.IGNORECASE) 
search_str = "My 11 Char String" 

res = re.match(pattern, search_str) 
print(len(res.groups())) # len = 4 
print (res.group(1)) #My 
print (res.group(2)) #11 
print (res.group(3)) #Char 
print (res.group(4)) #String 
+0

Creo que 'len (res.groups())' lanza una excepción cuando no se hace coincidir nada – abrasadera

0

Para esos momentos en que realmente quiere evitar la creación de listas:

import re 
import operator 
from functools import reduce 
count = reduce(operator.add, (1 for _ in re.finditer(my_pattern, my_string))) 

A veces puede que tenga que operar en grandes cadenas. Esto podría ayudar.

Cuestiones relacionadas