Saltar al contenido

¿Cuál es la diferencia entre re.search y re.match?

Después de de nuestra prolongada recopilación de datos pudimos resolver este atolladero que pueden tener muchos usuarios. Te regalamos la solución y nuestro deseo es serte de mucha ayuda.

Solución:

re.match está anclado al principio de la string. Eso no tiene nada que ver con los saltos de línea, por lo que no es lo mismo que usar ^ en el patrón

Como dice la documentación de re.match:

Si cero o más caracteres en el
comienzo de string coincide con el patrón de expresión regular, devuelve un correspondiente MatchObject ejemplo. Regreso None Si el string no coincide con el patrón; tenga en cuenta que esto es diferente de una coincidencia de longitud cero.

Nota: si desea ubicar una coincidencia en cualquier lugar stringutilizar search()
en lugar de.

re.search busca en todo stringcomo dice la documentación:

Escanear a través string buscando una ubicación donde el patrón de expresión regular produzca una coincidencia y devuelva un correspondiente MatchObject ejemplo. Regreso None si no hay posición en el
string coincide con el patrón; tenga en cuenta que esto es diferente de encontrar una coincidencia de longitud cero en algún punto de la
string.

Entonces, si necesita hacer coincidir al comienzo de la stringo para hacer coincidir todo el string utilizar match. Es mas rapido. De lo contrario, use search.

La documentación tiene un apartado específico para match contra search que también cubre cadenas multilínea:

Python ofrece dos operaciones primitivas diferentes basadas en expresiones regulares: match cheques para una coincidencia
solo al principio de El stringtiempo search cheques para una coincidencia
en cualquier sitio en el string (esto es lo que hace Perl por defecto).

Tenga en cuenta que match puede diferir de search
incluso cuando se usa una expresión regular que comienza con '^': '^' partidos sólo al comienzo de la stringo en
MULTILINE modo también inmediatamente después de una nueva línea. Los “match” operación exitosa sólo si el patrón coincide en el comienzo de El string

independientemente del modo, o en la posición inicial dada por el opcional pos
argumento independientemente de si un salto de línea lo precede.

Ahora, suficiente charla. Es hora de ver un 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

search ⇒ encontrar algo en cualquier parte del string y devolver un objeto de coincidencia.

match ⇒ encontrar algo en el comenzando de El string y devolver un objeto de coincidencia.

la coincidencia es mucho más rápida que la búsqueda, por lo que en lugar de hacer regex.search(“palabra”), puede hacer regex.match((.*?)palabra(.*?)) y obtener toneladas de rendimiento si está trabajando con millones de muestras

Este comentario de @ivan_bilan bajo la respuesta aceptada anterior me hizo pensar si tal cortar a tajos en realidad está acelerando cualquier cosa, así que averigüemos cuántas toneladas de rendimiento obtendrá realmente.

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 gráfica:

gráfico de línea de prueba de velocidad de expresión regular de coincidencia vs. búsqueda

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

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *