Pregunta

¿Cuál es la diferencia entre las funciones search () y match () en Python re module ?

He leído la documentación (< a href = "http://docs.python.org/2/library/re.html?highlight=matching%20searching#search-vs-match" rel = "noreferrer"> documentación actual ), pero Nunca parecen recordarlo. Sigo teniendo que buscarlo y volver a aprenderlo. Espero que alguien responda claramente con ejemplos para que (tal vez) se quede en mi cabeza. O al menos tendré un lugar mejor para regresar con mi pregunta y me llevará menos tiempo volver a aprenderla.

¿Fue útil?

Solución

re.match está anclado al comienzo de la cadena. Eso no tiene nada que ver con las líneas nuevas, por lo que no es lo mismo que usar ^ en el patrón.

Como la re.match documentación dice:

  

Si hay cero o más caracteres en la    principio de cadena coincide con el patrón de expresión regular, devuelve un    MatchObject correspondiente instancia.   Devuelve None si la cadena no lo hace   coincide con el patrón; nota que esto es   diferente de una coincidencia de longitud cero.

     

Nota: si quieres localizar una coincidencia   en cualquier lugar de la cadena, use search ()   en su lugar.

re.search busca en toda la cadena, como la documentación dice :

  

Escanear a través de una cadena buscando un   ubicación donde la expresión regular   patrón produce una coincidencia, y devuelve un    MatchObject correspondiente instancia.   Devuelva None si no hay una posición en el   cadena coincide con el patrón; tenga en cuenta que   esto es diferente de encontrar un   partido de longitud cero en algún punto de la   cadena.

Por lo tanto, si necesita hacer coincidir al principio de la cadena, o para hacer coincidir toda la cadena, use match . Es mas rapido. De lo contrario, utilice search .

La documentación tiene una sección específica para match vs. search que también cubre cadenas multilínea:

  

Python ofrece dos primitivas diferentes   operaciones basadas en regular   expresiones: match comprueba una coincidencia    solo al principio de la cadena,   mientras que search busca una coincidencia    en cualquier lugar en la cadena (esto es lo que   Perl lo hace por defecto).

     

Tenga en cuenta que match puede diferir de search   incluso cuando se usa una expresión regular   comenzando con '^' : '^' solo coincide   al comienzo de la cadena, o en   Modo MULTILINE también inmediatamente   siguiendo una nueva linea. El & # 8220; match & # 8221;   la operación tiene éxito solo si el patrón   coincidencias en el inicio de la cadena   independientemente del modo, o en el inicio   Posición dada por el opcional pos   argumento independientemente de si una   La nueva línea lo precede.

Ahora, basta de hablar. Es hora de ver algún código de ejemplo:

# example code:
string_with_newlines = """something
someotherthing"""

import re

print re.match('some', string_with_newlines) # matches
print re.match('someother', 
               string_with_newlines) # won't match
print re.match('^someother', string_with_newlines, 
               re.MULTILINE) # also won't match
print re.search('someother', 
                string_with_newlines) # finds something
print re.search('^someother', string_with_newlines, 
                re.MULTILINE) # also finds something

m = re.compile('thing, re.MULTILINE)

print m.match(string_with_newlines) # no match
print m.match(string_with_newlines, pos=4) # matches
print m.search(string_with_newlines, 
               re.MULTILINE) # also matches

Otros consejos

search ? encuentre algo en cualquier parte de la cadena y devuelva un objeto coincidente.

match ? encuentre algo al principio de la cadena y devuelva un objeto de coincidencia.

re.search search es para el patrón a lo largo de la cadena , mientras que re.match hace no buscar el patrón; si no lo hace, no tiene otra opción que hacer coincidir al comienzo de la cadena.

puede consultar el siguiente ejemplo para comprender el funcionamiento de re.match y re.search

a = "123abc"
t = re.match("[a-z]+",a)
t = re.search("[a-z]+",a)

re.match no devolverá ninguno, pero re.search devolverá abc.

La diferencia es que re.match () confunde a cualquiera que esté acostumbrado a Perl , grep o sed coincidencia de expresiones regulares, y re.search () no. :-)

Más sobrio, Como John D. Cook comenta , re.match ( ) " se comporta como si todos los patrones se hubieran precedido ^ " En otras palabras, re.match ('patrón') es igual a re.search ('^ patrón') . Así ancla el lado izquierdo de un patrón. Pero también no ancla el lado derecho de un patrón: que aún requiere un $ de terminación.

Francamente, dado lo anterior, creo que re.match () debería quedar en desuso. Me interesaría saber las razones por las que debería conservarse.

  

la coincidencia es mucho más rápida que la búsqueda, así que en lugar de hacer regex.search (" palabra ") puedes hacer regex.match ((. *?) word (. *?)) y ganar toneladas de rendimiento si eres trabajando con millones de muestras.

Este comentario de @ivan_bilan bajo el la respuesta aceptada arriba me hizo pensar si ese truco en realidad está acelerando algo, así que averigüemos cuántas toneladas de rendimiento realmente ganará.

Preparé el siguiente conjunto de pruebas:

import random
import re
import string
import time

LENGTH = 10
LIST_SIZE = 1000000

def generate_word():
    word = [random.choice(string.ascii_lowercase) for _ in range(LENGTH)]
    word = ''.join(word)
    return word

wordlist = [generate_word() for _ in range(LIST_SIZE)]

start = time.time()
[re.search('python', word) for word in wordlist]
print('search:', time.time() - start)

start = time.time()
[re.match('(.*?)python(.*?)', word) for word in wordlist]
print('match:', time.time() - start)

Hice 10 mediciones (1M, 2M, ..., 10M palabras) que me dieron la siguiente trama:

 coincidencia frente a búsqueda de expresiones regulares de expresión rápida

Las líneas resultantes son sorprendentemente (en realidad no tan sorprendentemente) rectas. Y la función search es (ligeramente) más rápida dada esta combinación de patrones específica. La moraleja de esta prueba: Evite sobre-optimizar su código.

re.match intenta hacer coincidir un patrón al principio de la cadena . re.search intenta hacer coincidir el patrón a lo largo de la cadena hasta que encuentre una coincidencia.

Mucho más corto:

  • search analiza toda la cadena.

  • match Hace solo el comienzo de la cadena.

El siguiente Ex lo dice:

>>> a = "123abc"
>>> re.match("[a-z]+",a)
None
>>> re.search("[a-z]+",a)
abc
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top