Adiciones adicionales a las expresiones regulares de Python (7)

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 IGNORECASElogotipo), 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 swordfishse 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\bcalificados 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 REsi 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á REsalgunos 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 Crowdebe 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 HTMLy XMLsiempre 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.VERBOSElogo es muy útil. Porque te permite editar el formato de la expresión regular para hacerla más clara.

re.VERBOSELos 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 FishCtal expresión y escasa legibilidad de IloveFishCla 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*$")

Supongo que te gusta

Origin blog.csdn.net/CSNN2019/article/details/114491601
Recomendado
Clasificación