Directorio de artículos
En este artículo señalaremos algunos de los errores más comunes.
Usar método de cadena
¡A veces, usar el módulo re es un error! Si hace coincidir una cadena fija o una clase de un solo carácter , y no tiene que usar ningún signo de re (como un IGNORECASE
logotipo), entonces no es necesario usar expresiones regulares. Las cadenas tienen algunos métodos para operar en cadenas fijas y, por lo general, son más rápidas. Debido a que todos son bucles pequeños en lenguaje C optimizados de forma independiente, el propósito es reemplazar el motor de expresión regular más potente y versátil en casos simples.
Por ejemplo, por ejemplo, si desea reemplazar todos los muertos en la cadena de palabras, pensaría en usar re.sub()
métodos de expresión regular para lograrlo, pero un reemplazo tan simple, o considerar el uso directo del replace()
método de cadena . Pero una cosa que debe tener en cuenta es que replace()
se reemplazará en la palabra interna, como swordfish
se convertirá sdeedfish
, ¡que obviamente no es lo que desea! replace () no tiene forma de identificar los límites de las palabras , por lo que debería considerar el uso de expresiones regulares . Los modelos RE solo necesitan estar \bword\b
calificados para esta tarea.
Otra situación común es eliminar un solo carácter de una cadena o reemplazarlo con otro carácter . Puede pensar en usar re.sub('\n', ' ', S)
expresiones para lograr algo tan positivo, pero de hecho el carácter del translate()
método es completamente capaz de realizar esta tarea y es más rápido que cualquier operación de expresión regular .
En resumen, antes de usar el módulo re, primero considere si su problema puede resolverse con un método más rápido y simple que viene con cadenas .
match () VS búsqueda ()
match()
La función solo verifica RE
si la coincidencia está al principio de la cadena y search()
recorrerá todo el contenido de la cadena de búsqueda que coincida . Es importante recordar esta distinción. Enfatice nuevamente, match()
solo informe una coincidencia exitosa, y la posición de coincidencia debe ser desde el primer carácter de la cadena :
>>> print(re.match('super', 'superstition').span())
(0, 5)
>>> print(re.match('super', 'insuperable'))
None
Por otro lado, la search()
función iterará a través de toda la cadena e informará la primera coincidencia que encuentre :
>>> print(re.search('super', 'superstition').span())
(0, 5)
>>> print(re.search('super', 'insuperable').span())
(2, 7)
A veces puede que Shuadian sea pequeño, inteligente, use re.match()
y luego agregue el frente RE .*
. Pero trata de no hacerlo, usando el mejor re.search()
sustituto . El compilador de expresiones regulares hará REs
algunos análisis, de modo que pueda aumentar la velocidad al buscar coincidencias . El análisis general primero descubrirá cuál es el primer personaje del partido. Por ejemplo, el patrón Crow
debe ser un carácter desde 'C'
el principio de una coincidencia, después de que los análisis del motor de coincidencia atraviesen rápidamente la cadena y luego comiencen 'C'
todas las coincidencias después de ser encontrado.
De acuerdo con el análisis anterior, agrega una .*
ventaja a la optimización de la falla, lo que requiere escanear de principio a fin nuevamente, y luego regresar para que coincida con la parte restante del RE. Entonces, use re.search()
en su lugar.
Codicioso vs no codicioso
Al repetir una expresión regular, si se usa a*
, el resultado es coincidir tanto como sea posible. Cuando intentas hacer coincidir un par de delimitadores simétricos, como los corchetes angulares en los logotipos HTML, el modo codicioso predeterminado te causará muchos problemas .
Veamos el siguiente ejemplo:
>>> s = '<html><head><title>Title</title>'
>>> len(s)
32
>>> print(re.match('<.*>', s).span())
(0, 32)
>>> print(re.match('<.*>', s).group())
<html><head><title>Title</title>
RE coincide en <html>
la <
parte trasera, .*
se consume la porción restante de la cuerda. Debido a que las expresiones regulares son codiciosas por defecto , RE debe rastrear carácter por carácter desde el final de la cadena hasta que encuentre una coincidencia>
. Podemos ver, de acuerdo con este método, que la coincidencia final que se encontró fue en realidad <html>
el <inicio hasta </title>
el> final. Obviamente, este no es el resultado que desea.
En este caso, la solución es usar calificadores no codiciosos *?、+?、??
o hacer {m,n}?
coincidir texto pequeño tanto como sea posible .
>>> print(re.match('<.*?>', s).group())
<html>
En el ejemplo anterior, >
el primero <
después de la coincidencia inmediatamente intenta hacer coincidir, si eso falla, más coincidencias en el motor anterior, pruebe un personaje hasta la primera coincidencia> , para que obtenga los resultados que queremos.
Tenga en cuenta que es doloroso utilizar expresiones regulares para analizar HTML y XML. Cuando escribes una expresión regular para manejar todas las situaciones posibles, encontrarás HTML
y XML
siempre romperás tus "reglas", te hace un quebradero de cabeza ... palabras como esta, se recomienda usar HTML y analizador XML para procesarlas más apropiadamente.
usar re.VERBOSE
Ahora debes darte cuenta de que la representación de expresiones regulares es muy compacta. Esto también trae un problema, es decir, no es fácil de leer. ** Las expresiones regulares moderadamente complejas pueden contener muchas barras invertidas, paréntesis y metacaracteres, lo que dificulta su lectura.
En estos REs
, al compilar una expresión regular para especificar cuando el re.VERBOSE
logo es muy útil. Porque te permite editar el formato de la expresión regular para hacerla más clara.
re.VERBOSE
Los letreros tienen varias funciones. Los caracteres de espacio en blanco que no están en la clase de caracteres de la expresión regular serán ignorados . Esto significa que como I love FishC
tal expresión y escasa legibilidad de IloveFishC
la misma. Sin embargo, [a b]
los caracteres coincidentes 'a', 'b' o ''; Además, puedes poner dentro de un RE comentarios, comentar desde el #
principio hasta la siguiente línea. Al usar cadenas entre comillas triples, hará que el formato de los RE sea más limpio:
pat = re.compile(r"""
\s* # Skip leading whitespace
(?P<header>[^:]+) # Header name
\s* : # Whitespace, and a colon
(?P<value>.*?) # The header's value -- *? used to
# lose the following trailing whitespace
\s*$ # Trailing whitespace to end-of-line
""", re.VERBOSE)
El mismo contenido, el siguiente es mucho más difícil de leer:
pat = re.compile(r"\s*(?P<header>[^:]+)\s*:(?P<value>.*?)\s*$")