re.match
está anclado al comienzo de la cadena. Eso no tiene nada que ver con las nuevas líneas, por lo que no es lo mismo que usar ^
en el patrón.
Como dice la documentación re.match :
Si cero o más caracteres al
comienzo de la cadena coinciden con el patrón de expresión regular, devuelve una MatchObject
instancia correspondiente . Regrese None
si la cadena 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 de la cadena, use search()
en su lugar.
re.search
busca en toda la cadena, como dice la documentación :
Explore a través de una cadena buscando una ubicación donde el patrón de expresión regular produzca una coincidencia y devuelva una MatchObject
instancia correspondiente . Devuelve None
si ninguna posición en la cadena 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 cadena.
Entonces, si necesita hacer coincidir al comienzo de la cadena, o para que coincida con toda la cadena, use match
. Es mas rapido. De lo contrario uso search
.
La documentación tiene una sección específica para match
vs.search
que también cubre cadenas multilínea:
Python ofrece dos operaciones primitivas diferentes basadas en expresiones regulares: match
busca una coincidencia
solo al comienzo de la cadena, mientras que search
busca una coincidencia
en cualquier parte de la cadena (esto es lo que hace Perl por defecto).
Tenga en cuenta que match
puede diferir search
incluso cuando se usa una expresión regular que comienza con '^'
: '^'
coincide solo al comienzo de la cadena, o en el
MULTILINE
modo también inmediatamente después de una nueva línea. La match
operación " " tiene éxito solo si el patrón coincide al comienzo de la cadena,
independientemente del modo, o en la posición inicial dada por el pos
argumento opcional, independientemente de si una nueva línea lo precede.
Ahora, basta de hablar. 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
match
lugar de más generalsearch
entonces? es por velocidad?match
? ¿Es una maniobra inteligente sembrar las API con nombres no intuitivos para obligarme a leer la documentación? ¡Todavía no lo haré! ¡Rebelde!match
parece un poco másfaster
que buscar cuando se usa la misma expresión regular, pero su ejemplo parece incorrecto según una prueba de rendimiento: stackoverflow.com/questions/180986/…search
⇒ encuentre algo en cualquier lugar de la cadena y devuelva un objeto de coincidencia.match
⇒ encuentre algo al comienzo de la cadena y devuelva un objeto de coincidencia.fuente
re.search
busca el patrón en toda la cadena , mientrasre.match
que no busca el patrón; si no es así, no tiene otra opción que hacerla coincidir al comienzo de la cadena.fuente
fullmatch
en phyton 3.4)?Este comentario de @ivan_bilan bajo la respuesta aceptada arriba me hizo pensar si tal truco realmente está acelerando algo, así que descubramos cuántas toneladas de rendimiento realmente obtendrás.
Preparé el siguiente conjunto de pruebas:
Hice 10 mediciones (1M, 2M, ..., 10M palabras) que me dieron la siguiente gráfica:
Las líneas resultantes son sorprendentemente (en realidad no tan sorprendentemente) rectas. Y la
search
función es (ligeramente) más rápida dada esta combinación de patrones específicos. La moraleja de esta prueba: evite optimizar demasiado su código.fuente
match
función sigue siendo más rápida que lasearch
función si se compara la misma expresión regular. Se puede comprobar en la secuencia de comandos mediante la comparaciónre.search('^python', word)
dere.match('python', word)
(ore.match('^python', word)
lo que es lo mismo, pero más fácil de entender si usted no lee la documentación y parece no afectar el rendimiento)match
función es generalmente más rápida. Elmatch
es más rápido cuando desea buscar al principio de la cadena,search
es más rápido cuando desea buscar en toda la cadena. Lo que corresponde con el sentido común. Es por eso que @ivan_bilan estaba equivocado: solíamatch
buscar en toda la cadena. Es por eso que tienes razón: solíasmatch
buscar al principio de la cadena. Si no está de acuerdo conmigo, trate de encontrar expresiones regulares paramatch
que sea más rápidore.search('python', word)
y haga el mismo trabajo.re.match('python')
es marginalmente más rápido quere.match('^python')
. Tiene que ser.match
función es un poco más rápida si desea buscar al principio de una cadena (en comparación con el uso de lasearch
función para encontrar una palabra al principio de una cadena con,re.search('^python', word)
por ejemplo). Pero me parece extraño, si le dice a lasearch
función que busque al principio de una cadena, debería ser tan rápida como lamatch
función.Puede consultar el siguiente ejemplo para comprender el funcionamiento
re.match
y la búsqueda.re.match
volveránone
, perore.search
volveráabc
.fuente
La diferencia es que
re.match()
engaña a cualquiera que esté acostumbrado a Perl , grep o sed coincidencia de expresiones regulares, yre.search()
no lo hace. :-)Más sobriamente, como señala John D. Cook ,
re.match()
"se comporta como si cada patrón ^ hubiera antepuesto". En otras palabras,re.match('pattern')
es igualre.search('^pattern')
. Por lo tanto, ancla el lado izquierdo de un patrón. Pero tampoco ancla el lado derecho de un patrón: eso todavía requiere una terminación$
.Francamente, dado lo anterior, creo que
re.match()
debería ser obsoleto. Me interesaría saber las razones por las que debería conservarse.fuente
re.match intenta hacer coincidir un patrón al comienzo de la cadena . re.search intenta hacer coincidir el patrón en toda la cadena hasta que encuentre una coincidencia.
fuente
Mucho más corto:
search
escanea toda la cadena.match
escanea solo el comienzo de la cadena.Siguiente Ex lo dice:
fuente