[Conceptos básicos de desarrollo de rastreadores de Python ②] Conceptos básicos de Python (expresiones regulares)

  • Recordatorio amistoso : dado que los artículos de esta columna están sesgados hacia los rastreadores, es imposible cubrir todo sobre python. Aquí solo nos centramos en los puntos clave.
    Si cree que hay algo que no se ha mencionado, bienvenido a agregar ~

  • Recomendaciones anteriores : [Conceptos básicos de desarrollo de rastreadores de Python ①] Conceptos básicos de Python (1)
    El artículo anterior ya ha hablado sobre los tipos de variables básicas de Python. Hoy veremos las "expresiones regulares" que Python usa con más frecuencia en el desarrollo de rastreadores.



1 ¿Qué es una expresión regular?

Una expresión regular (expresión regular, a menudo abreviada como regex, regexp o RE en el código) es una cadena con patrón que se usa para buscar, reemplazar, dividir y hacer coincidir datos de texto . La idea básica es usar algunos caracteres especiales para representar un patrón dado y luego hacer coincidir este patrón en el texto.

El papel de las expresiones regulares:

  1. Coincidencia : determine si una cadena dada cumple con la lógica de filtro de la expresión regular;
  2. Obtener subcadena : Podemos obtener la parte específica que queremos de la cadena a través de expresiones regulares.

Características de las expresiones regulares:

  1. Muy fuerte flexibilidad, lógica y funcionalidad ;
  2. El control complejo de cadenas se puede lograr rápidamente de una manera extremadamente simple .
  3. Para aquellos que son nuevos en contacto, es relativamente oscuro.

2 El uso de expresiones regulares en Python

En Python, el módulo re y el módulo regex se utilizan principalmente para implementar operaciones de expresiones regulares. Las siguientes son explicaciones detalladas respectivamente.

Módulo 2.1 re

El módulo re de Python (expresiones regulares) es una herramienta poderosa y flexible para la coincidencia de patrones, el reemplazo y la división de cadenas . El módulo re se puede usar para procesar una variedad de datos de caracteres, incluidos archivos de texto, archivos de registro, códigos de lenguaje de programación y más. El módulo re contiene una gran cantidad de funciones de expresiones regulares, que incluyen buscar, reemplazar, dividir, unir, copiar, extraer, etc., que pueden ayudar a los usuarios a completar tareas de procesamiento de texto eficientes.

Nota : Python viene con el módulo re, no se requiere instalación adicional. Por lo tanto, también es muy conveniente usar el módulo re sin ejecutar el comando pip install en la terminal, como instalar otras bibliotecas de terceros.

2.1.1 investigar()

re.search() es una función comúnmente utilizada en el módulo Python re, que se utiliza para buscar un patrón de expresión regular específico en una cadena . Al buscar, la función escaneará toda la cadena hasta que encuentre la primera subcadena que coincida con el patrón y luego devuelva un objeto coincidente (Coincidir con el objeto). Si no se encuentra ninguna subcadena coincidente, la función devuelve Ninguno.

Un uso común de la función re.search() es el siguiente:

match_object = re.search(pattern, string, flags=0)

Entre ellos, el parámetro de patrón indica la expresión regular que debe coincidir, el parámetro de cadena indica la cadena que debe coincidir y el parámetro de banderas indica la opción de coincidencia (por ejemplo, ignorar mayúsculas y minúsculas, etc.). Cuando la función devuelve un objeto coincidente, puede llamar al método match_object.group() para obtener la subcadena coincidente , y el parámetro de este método representa el número de serie de la subcadena que se obtendrá (si hay varios corchetes en la expresión regular , cada paréntesis indica un grupo cuyo número de serie aumenta de izquierda a derecha).

Por ejemplo, aquí hay un código de muestra para buscar una expresión regular en una cadena:

import re

text = "Python is a popular programming language"
pattern = "programming"
match_object = re.search(pattern, text)

if match_object:
    print("Found a match:", match_object.group())
else:
    print("No match found.")

Resultado de salida:

Found a match: programming

2.1.2 re.coincidencia()

En Python, el módulo re.match() es similar al módulo re.search(), que se usa para buscar coincidencias de expresiones regulares en cadenas. Sin embargo, re.match() solo coincidirá al principio de la cadena, y si no se encuentra ninguna coincidencia al principio, devolverá un objeto Ninguno . Por lo tanto, re.match() es más adecuado para escenarios que deben coincidir al principio de la cadena.

El uso de la función de coincidencia es el mismo que el de búsqueda. Echemos un vistazo a la misma cadena de prueba y el resultado devuelto por la coincidencia:

text = "Python is a popular programming language"
pattern = "programming"
match_object = re.match(pattern, text)

if match_object:
    print("Found a match:", match_object.group())
else:
    print("No match found.")

producción:

No match found.

Dado que la programación no es la primera palabra, no puede coincidir.

2.1.3 re.buscartodo()

re.findall() es otra función de coincidencia de patrones proporcionada por el módulo re en Python. Puede buscar todos los patrones que coincidan con expresiones regulares en una cadena y devolver una lista. Cada elemento de la lista es igual a la expresión regular. Coincidencia de patrones subcadena _ A diferencia de y
, se devuelven todas las coincidencias , no solo la primera o la última coincidencia. Por lo tanto, es una función muy útil si necesita encontrar todas las instancias de un patrón en un texto que coincidan con una determinada expresión regular .re.search()re.match()re.findall()re.findall()

Aquí hay un código de muestra para esta función:

import re

# 定义一个正则表达式,匹配以数字开头的子字符串
pattern = r'\d+'

# 定义一个待匹配的字符串
text = "Today is Oct 15, 2021, and the temperature is 20 degrees Celsius."

# 使用re.findall()函数查找所有匹配项,并将它们存储在一个list对象中
matches = re.findall(pattern, text)

# 输出匹配结果
print(matches)

En este ejemplo, primero definimos un patrón de expresión regular, r'\d+'para hacer coincidir las subcadenas que comienzan con un número. Luego, definimos una cadena para que coincida, text. Luego, re.findall()encontramos todas las coincidencias usando la función y las almacenamos en un objeto de lista, matches. Finalmente, mostramos los resultados coincidentes en la pantalla.

Resultado de salida:

['15', '2021', '20']

Esto se debe a que, en el texto del ejemplo, hay tres subcadenas que comienzan con un número, a saber, 15, 2021 y 20 grados. re.findall()la función los encuentra y los almacena en un objeto de lista.

2.1.4 re.sub()

re.sub() es otra función de coincidencia de patrones provista en el módulo re de Python, que se usa para reemplazar una subcadena que coincide con un cierto patrón en una cadena . La función re.sub() devuelve una nueva cadena en la que todas las subcadenas que coinciden con el patrón especificado se reemplazan con el contenido especificado.

Aquí hay un ejemplo de código simple de cómo usar re.sub() para la sustitución de cadenas:

import re

# 定义一个正则表达式,匹配所有'is'字符
pattern = 'is'

# 定义一个待匹配的字符串
text = "The pattern of the book is not easy to find."

# 使用re.sub()函数将匹配项替换为指定字符串
new_text = re.sub(pattern, "was", text)

# 输出结果
print(new_text)

En este ejemplo, primero definimos un patrón de expresión regular, 'is'que coincide con todos islos caracteres. Luego, definimos una cadena para que coincida, text. A continuación, usamos re.sub()la función para reemplazar todas las coincidencias con "was". Finalmente, generamos la nueva cadena después del reemplazo.

producción:

The pattern of the book was not easy to find.

Módulo de expresiones regulares 2.2

Además del módulo re en la biblioteca estándar, hay algunos módulos de expresiones regulares de terceros, como el módulo regex, que proporciona funciones que son más completas, avanzadas y compatibles con la sintaxis de expresiones regulares de Perl que el módulo re.

El módulo regex es similar al módulo re y proporciona la mayoría de las funciones del módulo re, pero admite más características y sintaxis de expresiones regulares, como aserciones complejas, atributos Unicode y estructuras anidadas coincidentes. Además, el rendimiento del módulo regex también es mejor que el del módulo re, que puede manejar expresiones regulares más grandes y datos de texto más extensos.

En resumen, hay muchos módulos de expresiones regulares en Python, entre los cuales el módulo re en la biblioteca estándar es el más utilizado. Si necesita una sintaxis y una funcionalidad más complejas cuando se trata de expresiones regulares, puede probar el módulo regex.


3 Clasificación de expresiones regulares

Una expresión regular consta de algunos caracteres ordinarios y algunos metacaracteres (metacaracteres). Los caracteres ordinarios incluyen letras y números en mayúsculas y minúsculas, mientras que los metacaracteres tienen significados especiales, que son los tokens que queremos usar para hacer coincidir.

3.1 Metacaracteres simples

metacarácter efecto
\ Coloca el siguiente token de carácter, una referencia inversa o un escape octal.
^ Coincide con el principio de la línea de entrada.
ps Coincide con el final de la línea de entrada.
(Asterisco)* Coincide con la subexpresión anterior cualquier número de veces.
(signo más) + Coincide con la subexpresión anterior una o más veces (mayor o igual que 1 vez).
? Coincide con la subexpresión anterior cero o una vez.

Código de muestra:

import re
# 匹配开头字符
res1 = re.match('^a', 'abandon')
print(res1)			# <re.Match object; span=(0, 1), match='a'>
print(res1.group())	# a
# 匹配结尾字符
res2 = re.match('.*d$', 'wood')
print(res2)			# <re.Match object; span=(0, 4), match='wood'>
print(res2.group())	# wood
# 匹配至少出现一次的字符
res3 = re.match('a+', 'aabcd')
print(res3)			# <re.Match object; span=(0, 2), match='aa'>
print(res3.group())	# aa
# 匹配一次或零次的字符
res4 = re.match('a?', 'aaabandon')
print(res4)			# <re.Match object; span=(0, 1), match='a'>
print(res4.group())	# a

3.2 Metacaracteres para la coincidencia de un solo carácter

metacarácter efecto
. (punto) Coincide con cualquier carácter individual excepto "\n" y "\r".
\d Coincide con un carácter numérico.
\D Coincide con un carácter no numérico.
\F Coincide con un carácter de avance de formulario.
\norte Coincide con un carácter de nueva línea.
\r Coincide con un retorno de carro.
\s Coincide con cualquier carácter invisible, incluidos espacios, tabulaciones, fuentes de formulario, etc.
\S Coincide con cualquier carácter visible.
\t Coincide con un carácter de tabulación.
\w Coincide con cualquier carácter de palabra, incluido un guión bajo.
\W Coincide con cualquier carácter que no sea una palabra.

Nota : agregue un signo más (+) después del metacarácter para que coincida con uno o más caracteres de este tipo

Ejemplo de código uno (.):

# 指定要匹配的模式
pattern = "py."
# 测试字符串1
test_str1 = "python"
result1 = re.match(pattern, test_str1)
print(result1)	# 输出 <re.Match object; span=(0, 3), match='pyt'>

Ejemplo de código 2 (\d, \D):

# 指定要匹配的模式
pattern = "\d"
# 测试字符串2
test_str2 = "The price is 199.99 dollars"
result2 = re.findall(pattern, test_str2)
print(result2)  # 输出['1', '9', '9', '9', '9']

# 指定要匹配的模式
pattern = "\D"

# 测试字符串3
test_str3 = "My phone number is 555-1234"
result3 = re.findall(pattern, test_str3)
print(result3)  # 输出 ['M', 'y', ' ', 'p', 'h', 'o', 'n', 'e', ' ', 'n', 'u', 'm', 'b', 'e', 'r', ' ', 'i', 's', ' ', '-']

Ejemplo de código cuatro (\s, \S):

# 指定要匹配的模式
pattern1 = r"\s+"  # 匹配一个或多个空白字符
pattern2 = r"\S+"  # 匹配一个或多个非空白字符

# 测试字符串1
test_str1 = "Hello\tworld\n"
result1 = re.findall(pattern1, test_str1)
print(result1)  # 输出 ['\t', '\n']

result2 = re.findall(pattern2, test_str1)
print(result2)  # 输出 ['Hello', 'world']

# 测试字符串2
test_str2 = " This is a demo. "
result3 = re.findall(pattern1, test_str2)
print(result3)  # 输出 [' ', ' ', ' ']

result4 = re.findall(pattern2, test_str2)
print(result4)  # 输出 ['This', 'is', 'a', 'demo.']

Ejemplo de código cuatro (\w, \W):

# 指定要匹配的模式
pattern1 = r"\w+"  # 匹配一个或多个单词字符
pattern2 = r"\W+"  # 匹配一个或多个非单词字符

# 测试字符串1
test_str1 = "Hello, world!"
result1 = re.findall(pattern1, test_str1)
print(result1)  # 输出 ['Hello', 'world']

result2 = re.findall(pattern2, test_str1)
print(result2)  # 输出 [', ', '!']

# 测试字符串2
test_str2 = "This is a demo."
result3 = re.findall(pattern1, test_str2)
print(result3)  # 输出 ['This', 'is', 'a', 'demo']

result4 = re.findall(pattern2, test_str2)
print(result4)  # 输出 [' ', ' ', ' ', '.']

3.3 Metacaracteres para coincidencia de conjuntos de caracteres

metacarácter efecto
[xyz] colección de personajes. Coincide con cualquiera de los caracteres contenidos.

Ejemplo de código :

import re

# 指定要匹配的模式
pattern1 = r"[aeiou]"  # 匹配任何元音字母
pattern2 = r"[A-Z]"   # 匹配任何大写字母

# 测试字符串1
test_str1 = "Hello, world!"
result1 = re.findall(pattern1, test_str1)
print(result1)  # 输出 ['e', 'o', 'o']

# 测试字符串2
test_str2 = "This is a Demo."
result2 = re.findall(pattern2, test_str2)
print(result2)  # 输出 ['T', 'D']

3.4 Metacaracteres para coincidencia de cuantificadores

metacarácter efecto
{norte} n es un entero no negativo. Coincidencia determinada n veces.
{norte,} n es un entero no negativo. Coincide al menos n veces.
{Nuevo Méjico} Tanto m como n son números enteros no negativos, donde n<=m. Coincidir al menos n veces y como máximo m veces.

Ejemplo de código :

import re

# 指定要匹配的模式
pattern1 = r"[a-z]{3}"  # 匹配任何由三个小写字母组成的连续子串
pattern2 = r"\d{2,3}"   # 匹配任何由两个或三个数字组成的连续子串

# 测试字符串1
test_str1 = "apple banana cherry"
result1 = re.match(pattern1, test_str1)
print(result1)  # 输出 <re.Match object; span=(0, 3), match='app'>

# 测试字符串2
test_str2 = "1234567890 12 123 1234"
result2 = re.findall(pattern2, test_str2)
print(result2)  # 输出 ['12', '123', '234']

3.5 Metacaracteres para emparejamiento de grupos

metacarácter efecto
() Defina la expresión entre ( y ) como un "grupo" y guarde los caracteres que coincidan con esta expresión en una tupla

código de muestra :

# 指定要匹配的模式
pattern1 = r"(\d{3})-(\d{4})-(\d{4})"  # 匹配格式为 3-4-4 的电话号码
pattern2 = r"<(\w+)>.*</\1>"   # 匹配任何形如 <tag>value</tag> 的 XML 节点

# 测试字符串1
test_str1 = "My phone number is 123-4567-8901."
result1 = re.search(pattern1, test_str1)
if result1:
    area_code, prefix, line_number = result1.groups()
    print("Area code: {}, Prefix: {}, Line number: {}".format(area_code, prefix, line_number))
else:
    print("No match.")

# 测试字符串2
test_str2 = "<title>This is a title</title>"
result2 = re.match(pattern2, test_str2)
if result2:
    tag = result2.group(1)
    print("Tag name: {}".format(tag))
else:
    print("No match.")

producción:

Area code: 123, Prefix: 4567, Line number: 8901
Tag name: title

En el ejemplo anterior, definimos dos patrones (\d{3})-(\d{4})-(\d{4})(donde ()significa usar el juego de caracteres que contiene como un grupo de captura, groups()y el contenido del grupo se puede obtener a través del método en el procesamiento posterior) y <(\w+)>.*</\1>(donde \1significa referirse a la primera captura contenido coincidente del grupo). Luego usamos re.searchla función para buscar dos cadenas de prueba diferentes para ver si coinciden con estos patrones. La primera cadena de prueba contiene un número de teléfono en el formato 3-4-4de , lo comparamos y luego extrajimos el código de área, el prefijo y la información del número de línea del número. Y la segunda cadena de prueba es un nodo XML, lo comparamos y luego extrajimos el nombre del nodo.
Puede modificar este ejemplo según sea necesario para implementar funciones de procesamiento de texto más complejas.

  • Finalmente, hay un metacarácter " | ", que se usa para realizar una operación lógica "o" (o) en dos condiciones coincidentes .

El código de ejemplo es el siguiente:

# 指定要匹配的模式
pattern = r"(cat|dog|bird)\d*"  # 匹配任何形如 cat\d* 或 dog\d* 或 bird\d* 的字符串

# 测试字符串
test_str = "I have a cat3 and a dog4 but no bird."
results = re.findall(pattern, test_str)
if results:
    print("Matching results: ", results)
else:
    print("No match.")

producción:

Matching results:  ['cat', 'dog', 'bird']

4 Equivalencia de expresiones regulares

Regex es difícil de entender porque hay un concepto de equivalencia en él. Este concepto aumenta enormemente la dificultad de comprensión y hace que muchos principiantes parezcan confundidos. Si restaura la equivalencia a la forma original de escribir, será muy simple escribir regular expresiones usted mismo, como hablar Es hora de escribir su expresión regular

?,*,+,\d,\w son todos caracteres equivalentes

  • ? Equivalente a la longitud coincidente {0,1}
  • *Equivalente a la longitud coincidente {0,}
  • + es equivalente a la longitud coincidente {1,}
  • \d es equivalente a [0-9]
  • \D es equivalente a [^0-9]
  • \w es equivalente a [A-Za-z_0-9]
  • \W es equivalente a [^A-Za-z_0-9].

5 coincidencias codiciosas

La coincidencia codiciosa y la coincidencia no codiciosa de expresiones regulares significan que cuando hay varios textos coincidentes posibles en la expresión regular, se eligen diferentes métodos de coincidencia.

La coincidencia codiciosa se refiere a la coincidencia de todas las cadenas calificadas tanto como sea posible al hacer coincidir, es decir, hacer coincidir primero los textos más largos . Por ejemplo, a.*bsignifica aque comienza con y btermina con , y cualquier carácter (incluidos los espacios) en el medio aparece al menos una vez, y el motor de expresiones regulares seleccionará tantos caracteres como sea posible desde el extremo izquierdo para cumplir la condición al hacer coincidir una cadena que cumple la regla. Por ejemplo, para cadenas abbbcbbbd, el resultado de la coincidencia codiciosa de esta expresión regular es abbbcbbb.

En consecuencia, la coincidencia no codiciosa también se denomina coincidencia perezosa o coincidencia mínima, que se refiere a hacer coincidir solo la cadena más corta que cumple las condiciones durante la coincidencia . De forma predeterminada, el motor de expresiones regulares adopta el modo de coincidencia codicioso, agregando un prefijo ?después de que el cuantificador pueda convertirlo en un modo de coincidencia no codicioso . Por ejemplo, a.*?bsignifica que acomienza y btermina con , y cualquier carácter (incluidos los espacios) en el medio aparece al menos una vez, y ?después de agregar , significa que esta regla se cumple en la condición más breve posible. Por ejemplo, para cadenas abbbcbbbd, el resultado de coincidencia no codicioso de esta expresión regular es abb.

  • La coincidencia voraz o no voraz de expresiones regulares depende de si hay un signo de interrogación después del cuantificador, que debe determinarse de acuerdo con las necesidades reales. Tenga en cuenta que, si bien no codicioso es generalmente más seguro y más confiable, también incurre en una penalización de rendimiento ya que el motor necesita seguir retrocediendo para encontrar texto elegible.

código de muestra :

# 原始字符串
str1 = "hello-world-and-hi"

# 贪婪匹配,获取第一个连字符到最后一个连字符之间的所有字符
result1_greedy = re.findall(r"-.*-", str1)
print(result1_greedy)    # 输出 ['-world-and-']

# 非贪婪匹配,只获取第一个连字符到第二个连字符之间的所有字符
result1_non_greedy = re.findall(r"-\w+?-", str1) 
print(result1_non_greedy)   # 输出 ['-world-']

# 原始字符串
s = "hello world, this is a test string."

# 贪婪匹配,获取以 h 开头、以空格结尾的所有字符
result_greedy = re.findall(r"h.* ", s)
print(result_greedy)	# ['hello world, this is a test ']

# 非贪婪匹配,获取以 h 开头、以空格结尾的最短字符
result_non_greedy = re.findall(r"h.*? ", s)
print(result_non_greedy)	# ['hello ', 'his ']

Supongo que te gusta

Origin blog.csdn.net/z135733/article/details/131078962
Recomendado
Clasificación