Python avanzado: expresiones regulares

¿Cuál es el uso?

Veamos un ejemplo.

Un archivo de texto almacena cierta información de posición de mercado, el formato es el siguiente

Python3 高级开发工程师 上海互教教育科技有限公司上海-浦东新区2万/月02-18满员
测试开发工程师(C++/python) 上海墨鹍数码科技有限公司上海-浦东新区2.5万/每月02-18未满员
Python3 开发工程师 上海德拓信息技术股份有限公司上海-徐汇区1.3万/每月02-18剩余11人
测试开发工程师(Python) 赫里普(上海)信息科技有限公司上海-浦东新区1.1万/每月02-18剩余5人
Python高级开发工程师 上海行动教育科技股份有限公司上海-闵行区2.8万/月02-18剩余255人
python开发工程师 上海优似腾软件开发有限公司上海-浦东新区2.5万/每月02-18满员

Ahora, necesitamos escribir un programa para obtener los salarios de todos los puestos de estos textos.

es obtener resultados como este

2
2.5
1.3
1.1
2.8
2.5

¿Cómo hacerlo?
 

Este es el procesamiento típico de cadenas.

Analizando las reglas aquí, podemos encontrar que hay palabras clave  万/月 o 万/每月

escribir el siguiente código

content = '''
Python3 高级开发工程师 上海互教教育科技有限公司上海-浦东新区2万/月02-18满员
测试开发工程师(C++/python) 上海墨鹍数码科技有限公司上海-浦东新区2.5万/每月02-18未满员
Python3 开发工程师 上海德拓信息技术股份有限公司上海-徐汇区1.3万/每月02-18剩余11人
测试开发工程师(Python) 赫里普(上海)信息科技有限公司上海-浦东新区1.1万/每月02-18剩余5人
Python高级开发工程师 上海行动教育科技股份有限公司上海-闵行区2.8万/月02-18剩余255人
python开发工程师 上海优似腾软件开发有限公司上海-浦东新区2.5万/每月02-18满员
'''

# 将文本内容按行放入列表
lines = content.splitlines()
for line in lines:
    # 查找'万/月' 在 字符串中什么地方
    pos2 = line.find('万/月')
    if pos2 < 0:
        # 查找'万/每月' 在 字符串中什么地方
        pos2 = line.find('万/每月')
        # 都找不到
        if pos2 < 0: 
            continue

    # 执行到这里,说明可以找到薪资关键字
    # 接下来分析 薪资 数字的起始位置
    # 方法是 找到 pos2 前面薪资数字开始的位置
    idx = pos2-1

    # 只要是数字或者小数点,就继续往前面找
    while line[idx].isdigit() or line[idx]=='.':
        idx -= 1

    # 现在 idx 指向 薪资数字前面的那个字,
    # 所以薪资开始的 索引 就是 idx+1
    pos1 = idx + 1

    print(line[pos1:pos2])

 ¿ Hay una manera más fácil para esto ? 从字符串中搜索出某种特征的子串

La solución es lo que vamos a presentar hoy  正则表达式 .


Si usamos expresiones regulares, el código puede ser así

content = '''
Python3 高级开发工程师 上海互教教育科技有限公司上海-浦东新区2万/月02-18满员
测试开发工程师(C++/python) 上海墨鹍数码科技有限公司上海-浦东新区2.5万/每月02-18未满员
Python3 开发工程师 上海德拓信息技术股份有限公司上海-徐汇区1.3万/每月02-18剩余11人
测试开发工程师(Python) 赫里普(上海)信息科技有限公司上海-浦东新区1.1万/每月02-18剩余5人
Python高级开发工程师 上海行动教育科技股份有限公司上海-闵行区2.8万/月02-18剩余255人
python开发工程师 上海优似腾软件开发有限公司上海-浦东新区2.5万/每月02-18满员
'''

import re
for one in  re.findall(r'([\d.]+)万/每{0,1}月', content):
    print(one)

Ejecútalo y verás, el resultado es el mismo.

Pero el código es mucho más simple.

Una expresión regular es una sintaxis utilizada para describir las características de la cadena que desea buscar.

Aquí se especifica una expresión regular

re.findall(r'([\d.]+)万/每{0,1}月', content)

([\d.]+)万/每{0,1}月 , que es una cadena de expresión regular que especifica las características de la subcadena de búsqueda.

¿Por qué escribes eso? Lo presentaremos más adelante.

La función findall devuelve todas las subcadenas coincidentes en una lista.

Como se puede ver en el ejemplo anterior, la clave para usar expresiones regulares es  如何写出正确的表达式语法 .

Haga clic aquí para consultar la descripción en la documentación oficial de Python  . Los detalles de uso específicos, incluida la sintaxis, están dentro.

Este tutorial le presentará algunas sintaxis comunes de expresiones regulares.

verificación en línea

¿Cómo verificar si la expresión que escribió puede coincidir correctamente con la cadena que se busca?

Puede visitar esta URL:  regex101: compilar, probar y depurar expresiones regulares

Ingrese el texto de búsqueda y la expresión de acuerdo con la imagen esquemática a continuación para ver si su expresión puede coincidir correctamente con la cadena.

El sitio web de verificación anterior está en el extranjero, si no puede acceder a él, pruebe este sitio web nacional de verificación de expresiones regulares

gramática común

Los caracteres ordinarios escritos en expresiones regulares significan: Emparejarlos directamente.

Por ejemplo, en su texto a continuación, si desea encontrar todas las pruebas, la expresión regular es muy simple, solo ingrese prueba directamente.

Como sigue:

Lo mismo es cierto para los caracteres chinos. Para encontrar caracteres chinos, simplemente escríbalos directamente en la expresión regular.


Pero hay algunos caracteres especiales, el término se llama metacharacters (metacaracteres) .

Aparecen en la cadena de expresión regular, no para que coincidan directamente, sino para expresar algún significado especial.

Estos metacaracteres especiales incluyen lo siguiente:

. * + ? \ [ ] ^ $ { } | ( )

Vamos a introducir sus significados por separado:

punto - coincide con todos los caracteres

. significa hacer coincidir  换行符 cualquier  carácter excepto . 单个

Por ejemplo, desea seleccionar todos los colores del texto a continuación.

苹果是绿色的
橙子是橙色的
香蕉是黄色的
乌鸦是黑色的

Eso es encontrar todas   las palabras que terminan e incluyen el carácter anterior.

Puedes escribir expresiones regulares como esta  . .色

El punto representa cualquier carácter, tenga en cuenta que es un carácter.

.色 Combinarlos significa buscar cualquier carácter seguido de la palabra color y combinar los dos caracteres

Verifíquelo, como se muestra en la siguiente figura.

Siempre que la expresión sea correcta, se puede escribir en código Python, de la siguiente manera

content = '''苹果是绿色的
橙子是橙色的
香蕉是黄色的
乌鸦是黑色的'''

import re
p = re.compile(r'.色')
for one in  p.findall(content):
    print(one)

El resultado de la operación es el siguiente

绿色
橙色
黄色
黑色

Asterisco: repite el partido cualquier número de veces

* Indica que coincide con la subexpresión anterior cualquier número de veces, incluidas 0 veces.

Por ejemplo, desea seleccionar el contenido de la cadena después de la coma en cada línea, incluida la coma misma, del texto a continuación. Tenga en cuenta que las comas aquí son comas chinas.

苹果,是绿色的
橙子,是橙色的
香蕉,是黄色的
乌鸦,是黑色的
猴子,

Puedes escribir expresiones regulares como esta  ,.* .

  • Inmediatamente después de ., significa que cualquier carácter puede aparecer cualquier número de veces, por lo que la expresión completa significa todos los caracteres después de la coma, incluida la coma.

Verifíquelo, como se muestra en la siguiente figura.

Especialmente en la última línea, no hay otros caracteres después de la coma del mono, pero * significa que puede coincidir 0 veces, por lo que la expresión también es válida.

Siempre que la expresión sea correcta, se puede escribir en código Python, de la siguiente manera

content = '''苹果,是绿色的
橙子,是橙色的
香蕉,是黄色的
乌鸦,是黑色的
猴子,'''

import re
p = re.compile(r',.*')
for one in  p.findall(content):
    print(one)

El resultado de la operación es el siguiente

,是绿色的
,是橙色的
,是黄色的
,是黑色的
,

Tenga en cuenta que .* es muy común en expresiones regulares y significa hacer coincidir cualquier carácter cualquier número de veces.

Por supuesto, este * no tiene que ir precedido de puntos , también pueden ser otros caracteres, como

signo más: repite la coincidencia varias veces

significa coincidir con la subexpresión anterior una o más veces, excluyendo 0 veces .

Por ejemplo, aún en el ejemplo anterior, debe seleccionar el contenido de la cadena después de la coma en cada línea del texto, incluida la coma misma.

Pero agregue una condición, si no hay contenido después de la coma, no lo elija.

Por ejemplo, en el texto a continuación, si no hay contenido después de la coma en la última línea, no lo seleccione.

苹果,是绿色的
橙子,是橙色的
香蕉,是黄色的
乌鸦,是黑色的
猴子,

Puedes escribir expresiones regulares como esta  ,.+ .

Verifíquelo, como se muestra en la siguiente figura.

En la última línea, no hay otros caracteres después de la coma del mono, y + significa al menos una coincidencia, por lo que no hay una subcadena seleccionada en la última línea.

signo de interrogación - coincidencias 0-1 veces

? Indica que la subexpresión anterior coincide 0 o 1 veces.

Por ejemplo, sigue siendo el ejemplo anterior, desea seleccionar 1 carácter después de la coma en cada línea del texto, incluida la coma misma.

苹果,绿色的
橙子,橙色的
香蕉,黄色的
乌鸦,黑色的
猴子,

Puedes escribir expresiones regulares como esta  . ,.?

Verifíquelo, como se muestra en la siguiente figura.

En la última línea, no hay otros caracteres después de la coma del mono, pero ? significa coincidencias 1 o 0 veces, por lo que también se selecciona un carácter de coma en la última línea.

llaves - coinciden con el número especificado de veces

Las llaves indican que el carácter anterior coincide con  指定的次数 .

Por ejemplo, el siguiente texto

红彤彤,绿油油,黑乎乎,绿油油油油

La expresión  油{3} significa hacer coincidir caracteres de aceite consecutivos 3 veces

La expresión  油{3,4} significa hacer coincidir caracteres de aceite consecutivos al menos 3 veces y como máximo 4 veces

Solo puede coincidir con este último, como se muestra a continuación:

Codiciosos y no codiciosos

Queremos extraer todas las etiquetas html en la siguiente cadena,

source = '<html><head><title>Title</title>'

obtener una lista como esta

['<html>', '<head>', '<title>', '</title>']

Es fácil pensar en usar expresiones regulares <.*>

Escribe el siguiente código

source = '<html><head><title>Title</title>'

import re
p = re.compile(r'<.*>')

print(p.findall(source))

Pero el resultado de ejecución es

['<html><head><title>Title</title>']

¿qué pasó? Resulta que en las expresiones regulares, '*', '+', '?' son todos codiciosos. Al usarlos, coincidirán tanto como sea posible.

Por lo tanto,  <.*> el asterisco in (que indica cualquier número de repeticiones) se ha emparejado con la e al final de la cadena. </title> 

Para resolver este problema, debe usar el modo no codicioso, es decir, agregarlo después del asterisco  ? y se vuelve así <.*?>

código cambiado a

source = '<html><head><title>Title</title>'

import re
# 注意多出的问号
p = re.compile(r'<.*?>')

print(p.findall(source))

Ejecútalo de nuevo y debería funcionar.

Metacaracteres de escape

Las barras invertidas se utilizan de diversas formas en las expresiones regulares. \ 

Por ejemplo, queremos buscar todas las cadenas que preceden a un punto en el texto a continuación, incluido el punto en sí.

苹果.是绿色的
橙子.是橙色的
香蕉.是黄色的

Si escribimos expresiones regulares como esta  .*. , debes ser inteligente y encontrar que algo anda mal.

Dado que el punto es un metacarácter , aparece directamente en la expresión regular, lo que significa que coincide con cualquier carácter individual y no puede representar el significado del carácter en sí.

¿Cómo hacerlo?

Si el contenido que queremos buscar contiene metacaracteres, podemos escaparlos con barras invertidas .

Aquí usamos expresiones como esta: .*\.

Por ejemplo, el programa Python es el siguiente

content = '''苹果.是绿色的
橙子.是橙色的
香蕉.是黄色的'''

import re
p = re.compile(r'.*\.')
for one in  p.findall(content):
    print(one)

El resultado de la operación es el siguiente

苹果.
橙子.
香蕉.

coincidir con un determinado tipo de carácter

Una cantidad de caracteres seguidos de una barra invertida indica  某种类型 un solo carácter que debe coincidir.

Por ejemplo

\d coincide con cualquier carácter numérico entre 0-9, equivalente a la expresión [0-9]

\D coincide con cualquier carácter que no sea un número entre 0 y 9, equivalente a la expresión [^0-9]

\s coincide con cualquier carácter en blanco, incluidos espacios, tabulaciones, saltos de línea, etc., equivalente a la expresión [\t\n\r\f\v]

\S coincide con cualquier carácter que no esté en blanco, equivalente a la expresión [^ \t\n\r\f\v]

\w coincide con cualquier carácter de texto, incluidas letras mayúsculas y minúsculas, números y guiones bajos, lo que equivale a la expresión [a-zA-Z0-9_]

De forma predeterminada, también se incluyen caracteres de texto Unicode.Si se especifican etiquetas de código ASCII, solo se incluyen letras ASCII.

\W coincide con cualquier carácter no literal, equivalente a la expresión [^a-zA-Z0-9_]

Las barras invertidas también se pueden usar dentro de corchetes, como [\s,.] para hacer coincidir: cualquier carácter en blanco, coma o punto

corchetes: coincide con uno de varios caracteres

Los corchetes indican que coincida con uno de los caracteres especificados.

Por ejemplo

[abc] Puede coincidir con cualquier carácter en a, b o c. equivalente a [a-c]  .

[a-c] A - en el medio indica un rango de a a c.

Si desea hacer coincidir todas las letras minúsculas, puede utilizar [a-z]

Algunos metacaracteres pierden su magia dentro de los corchetes y se vuelven como personajes normales.

Por ejemplo

[akm.] coincidir  a k m . con cualquier carácter en

Aquí,  . entre paréntesis, ya no significa coincidir con ningún carácter, sino coincidir con  . este carácter.


Si se usa entre corchetes  ^ , significa   el conjunto de caracteres dentro de los corchetes.

Por ejemplo

content = 'a1b2c3d4e5'

import re
p = re.compile(r'[^\d]' )
for one in  p.findall(content):
    print(one)

[^\d] Indica que seleccione caracteres no numéricos

La salida es:

a
b
c
d
e

Posición inicial, final y modo de una sola línea, varias líneas

^ Indica la ubicación del texto coincidente. 开头 

Las expresiones regulares se pueden establecer  单行模式 y 多行模式

En caso afirmativo  单行模式 , indica  整个文本 la posición inicial del partido.

En caso afirmativo  多行模式 , indica  文本每行 la posición inicial del partido.

Por ejemplo, en el siguiente texto, el número en la parte superior de cada línea indica el número de la fruta y el último número indica el precio

001-苹果价格-60,
002-橙子价格-70,
003-香蕉价格-80,

Si queremos extraer todos los números de frutas, use una expresión regular como esta ^\d+

La expresión regular anterior, utilizada en el programa Python, es la siguiente

content = '''001-苹果价格-60
002-橙子价格-70
003-香蕉价格-80'''

import re
p = re.compile(r'^\d+', re.M)
for one in  p.findall(content):
    print(one)

Tenga en cuenta que el segundo parámetro re.M de compilación indica el uso del modo multilínea,

El resultado de la operación es el siguiente

001
002
003

Si se elimina el segundo parámetro re.M de compilación, los resultados de ejecución son los siguientes

001

Solo existe la primera línea.

Porque en el modo de una sola línea, ^ solo coincidirá con el comienzo de todo el texto.


$ Indica  结尾 la ubicación del texto coincidente.

Si es así  单行模式 , indica  整个文本 la posición final del partido.

Si es así , indica la posición final del partido. 多行模式  文本每行 

Por ejemplo, en el siguiente texto, el número en la parte superior de cada línea indica el número de la fruta y el último número indica el precio

001-苹果价格-60,
002-橙子价格-70,
003-香蕉价格-80,

Si queremos extraer todos los números de frutas, use una expresión regular como esta \d+$

código correspondiente

content = '''001-苹果价格-60
002-橙子价格-70
003-香蕉价格-80'''

import re
p = re.compile(r'\d+$', re.MULTILINE)
for one in  p.findall(content):
    print(one)

Tenga en cuenta que el segundo parámetro de compilación, re.MULTILINE, indica el uso del modo multilínea,

El resultado de la operación es el siguiente

60
70
80

Si se elimina el segundo parámetro re.MULTILINE de compilación, los resultados de ejecución son los siguientes

80

Sólo está la última línea.

Porque en el modo de una sola línea, $ solo coincidirá con la posición final de todo el texto.

barra vertical - coincide con uno de los

Una barra vertical significa coincidir con uno de ellos.

Por ejemplo,

En particular, debe tenerse en cuenta que las líneas verticales tienen la prioridad más baja en las expresiones regulares, lo que significa que las partes separadas por líneas verticales son un todo.

Por ejemplo, significa hacer coincidir es  o   , 绿色|橙  绿色

en lugar de  o  绿色绿橙

paréntesis - agrupación

Los paréntesis se denominan selección de grupo de la expresión regular.

 Es para marcar el contenido que coincide con la expresión regular  其中的某些部分 como un grupo determinado.

多个 Podemos marcar grupos en la expresión regular 

¿Por qué existe un concepto de grupo? Porque a menudo necesitamos extraer información sobre ciertas partes del contenido coincidente.

Anteriormente, tuvimos un ejemplo, del texto a continuación, que también selecciona las cadenas que preceden a las comas en cada línea .包括逗号本身 

苹果,苹果是绿色的
橙子,橙子是橙色的
香蕉,香蕉是黄色的

Puedes escribir expresiones regulares como esta  ^.*, .

Pero, ¿y si pidiéramos  no incluir comas  ?

Por supuesto que no puedes escribir directamente así. ^.*

Debido a que la última coma es la función, si la elimina, no podrá encontrar la que está antes de la coma.

Pero poner comas en la expresión regular, nuevamente incluye comas.

La solución al problema es usar selectores de grupo: paréntesis .

Escribimos así  ^(.*), , el resultado es el siguiente

Puede encontrar que ponemos entre paréntesis la parte que se va a extraer de la expresión completa, para que los nombres de las frutas se coloquen solos en el grupo.

El código Python correspondiente es el siguiente

content = '''苹果,苹果是绿色的
橙子,橙子是橙色的
香蕉,香蕉是黄色的'''

import re
p = re.compile(r'^(.*),', re.MULTILINE)
for one in  p.findall(content):
    print(one)

La agrupación también se puede utilizar varias veces.

Por ejemplo, queremos extraer el nombre de cada persona y el número de teléfono móvil correspondiente del siguiente texto

张三,手机号码15945678901
李四,手机号码13945677701
王二,手机号码13845666901

Se puede usar una expresión regular como esta ^(.+),.+(\d{11})

El siguiente código se puede escribir

content = '''张三,手机号码15945678901
李四,手机号码13945677701
王二,手机号码13845666901'''

import re
p = re.compile(r'^(.+),.+(\d{11})', re.MULTILINE)
for one in  p.findall(content):
    print(one)

Cuando hay varios grupos, podemos usar  (?P<分组名>...) este formato para nombrar cada grupo.

La ventaja de esto es que es más conveniente que los códigos posteriores extraigan el contenido de cada grupo

Por ejemplo

content = '''张三,手机号码15945678901
李四,手机号码13945677701
王二,手机号码13845666901'''

import re
p = re.compile(r'^(?P<name>.+),.+(?P<phone>\d{11})', re.MULTILINE)
for match in  p.finditer(content):
    print(match.group('name'))
    print(match.group('phone'))

dejar que el punto coincida con la nueva línea

Como dije antes,   sí  不匹配换行符 , pero a veces, la cadena de características es una línea cruzada, por ejemplo, para encontrar todos los títulos de trabajo en el siguiente texto.

<div class="el">
        <p class="t1">           
            <span>
                <a>Python开发工程师</a>
            </span>
        </p>
        <span class="t2">南京</span>
        <span class="t3">1.5-2万/月</span>
</div>
<div class="el">
        <p class="t1">
            <span>
                <a>java开发工程师</a>
            </span>
		</p>
        <span class="t2">苏州</span>
        <span class="t3">1.5-2/月</span>
</div>

Si usa la expresión directamente,  class=\"t1\">.*?<a>(.*?)</a> encontrará que no coincidirá, porque   hay dos líneas en blanco entre t1 y  .<a>

En este momento necesita  点也匹配换行符 , puede usar  DOTALL parámetros

como esto

content = '''
<div class="el">
        <p class="t1">           
            <span>
                <a>Python开发工程师</a>
            </span>
        </p>
        <span class="t2">南京</span>
        <span class="t3">1.5-2万/月</span>
</div>
<div class="el">
        <p class="t1">
            <span>
                <a>java开发工程师</a>
            </span>
		</p>
        <span class="t2">苏州</span>
        <span class="t3">1.5-2/月</span>
</div>
'''

import re
p = re.compile(r'class=\"t1\">.*?<a>(.*?)</a>', re.DOTALL)
for one in  p.findall(content):
    print(one)

volver al ejemplo del principio

Con el conocimiento anterior, veamos el ejemplo al principio de este artículo.

Tome los salarios para todos los puestos del texto a continuación.

Python3 高级开发工程师 上海互教教育科技有限公司上海-浦东新区2万/月02-18满员
测试开发工程师(C++/python) 上海墨鹍数码科技有限公司上海-浦东新区2.5万/每月02-18未满员
Python3 开发工程师 上海德拓信息技术股份有限公司上海-徐汇区1.3万/每月02-18剩余11人
测试开发工程师(Python) 赫里普(上海)信息科技有限公司上海-浦东新区1.1万/每月02-18剩余5人

La expresión que usamos es ([\d.]+)万/每{0,1}月

¿Por qué lo escribes así?

[\d.]+ Significa hacer coincidir múltiples ocurrencias de un número o punto. Esto coincidiría con números como: 3 33 33.33

万/每{0,1}月 es inmediatamente después, si no hay esto, coincidirá con otros números, como 3 en Python3.

Entre ellos  , esta parte significa que  cada personaje puede aparecer 0 o 1 veces en el partido. 每{0,1}月 每月

¿ Hay otra forma de expresar esto  每{0,1}月 ?

También se puede usar porque el signo de interrogación significa que el carácter anterior coincide 0 o 1 veces 每?月 

cortar hilo

Los métodos del objeto de cadena solo son adecuados para la división simple de cadenas. A veces, necesita un corte de hilo más flexible. split 

Por ejemplo, necesitamos extraer el nombre del general de la siguiente cadena.

names = '关羽; 张飞, 赵云,马超, 黄忠  李逵'

Encontramos que algunos de estos nombres están separados por punto y coma, algunos están separados por comas y otros están separados por espacios, y hay un número indefinido de espacios alrededor del separador.

En este momento, puede usar el método de división en la expresión regular:

import re

names = '关羽; 张飞, 赵云,   马超, 黄忠  李逵'

namelist = re.split(r'[;,\s]\s*', names)
print(namelist)

La expresión regular  [;,\s]\s* especifica que el delimitador puede ser punto y coma, coma y espacio, y puede haber un número indefinido de espacios alrededor del símbolo.

reemplazo de cadena

reemplazo de patrón de coincidencia

Los métodos del objeto String  replace solo son adecuados para sustituciones simples. A veces, necesita una sustitución de cadenas más flexible.

Por ejemplo, necesitamos encontrar todos los enlaces en el siguiente texto que  /avxxxxxx/ comienzan  /av con , seguidos de una serie de números y la cadena de este patrón.

Estas cadenas se reemplazan todas con  /cn345677/ .

names = '''

下面是这学期要学习的课程:

<a href='https://www.bilibili.com/video/av66771949/?p=1' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是牛顿第2运动定律

<a href='https://www.bilibili.com/video/av46349552/?p=125' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是毕达哥拉斯公式

<a href='https://www.bilibili.com/video/av90571967/?p=33' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是切割磁力线
'''

El contenido que se va a reemplazar no es fijo, por lo que no se puede usar el método de reemplazo de la cadena.

En este momento, puede usar el método sub en la expresión regular:

import re

names = '''

下面是这学期要学习的课程:

<a href='https://www.bilibili.com/video/av66771949/?p=1' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是牛顿第2运动定律

<a href='https://www.bilibili.com/video/av46349552/?p=125' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是毕达哥拉斯公式

<a href='https://www.bilibili.com/video/av90571967/?p=33' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是切割磁力线
'''

newStr = re.sub(r'/av\d+?/', '/cn345677/' , names)
print(newStr)

El método sub también es para reemplazar cadenas, pero el contenido reemplazado usa expresiones regulares para representar todas las cadenas que cumplen con las características.

 Por ejemplo, aquí está la expresión regular del  primer parámetro , lo que significa que una  cadena de caracteres  que comienza con , seguida de una cadena de números y  termina con , debe reemplazarse. /av\d+?//av/

El segundo parámetro, aquí está  '/cn345677/' esta cadena, que indica qué reemplazar.

El tercer parámetro es la cadena de origen.

Especificar una función de reemplazo

En el ejemplo anterior, lo que solíamos reemplazar era una cadena fija  /cn345677/.

Si requerimos que el contenido después del reemplazo sea el número original + 6, por ejemplo,  reemplácelo con  . /av66771949/ /av66771955/

Para este reemplazo más complejo, podemos usar el segundo parámetro de sub  指定为一个函数 , el valor de retorno de la función, para que sea la cadena utilizada para el reemplazo.

como sigue

import re

names = '''

下面是这学期要学习的课程:

<a href='https://www.bilibili.com/video/av66771949/?p=1' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是牛顿第2运动定律

<a href='https://www.bilibili.com/video/av46349552/?p=125' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是毕达哥拉斯公式

<a href='https://www.bilibili.com/video/av90571967/?p=33' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是切割磁力线
'''

# 替换函数,参数是 Match对象
def subFunc(match):
    # Match对象 的 group(0) 返回的是整个匹配上的字符串, 
    src = match.group(0)
    
    # Match对象 的 group(1) 返回的是第一个group分组的内容
    number = int(match.group(1)) + 6
    dest = f'/av{number}/'

    print(f'{src} 替换为 {dest}')

    # 返回值就是最终替换的字符串
    return dest

newStr = re.sub(r'/av(\d+?)/', subFunc , names)
print(newStr)

Obtener la cadena en el grupo, de la siguiente manera

match.group(0) # 获取整个匹配字符串
match.group(1) # 获取第1个组内字符串
match.group(2) # 获取第2个组内字符串

En las versiones posteriores a Python 3.6, el método de escritura también puede ser más conciso, utilizando directamente subíndices como una lista, de la siguiente manera

match[0]
match[1]
match[2]

En el ejemplo anterior:

Cuando se ejecuta la función de expresión regular re.sub,  la subcadena coincidente será: 每发现一个

  • Crear una instancia de un objeto de coincidencia

    Este objeto de coincidencia contiene información sobre esta coincidencia, como: cuál es la cadena completa, cuál es la parte coincidente de la cadena y cuáles son las cadenas de grupo en ella

  • Llame y ejecute el segundo objeto de parámetro de la subfunción, es decir, llame a la función de devolución de llamada subFunc

    Y pase el objeto de coincidencia recién generado como parámetro a subFunc

Supongo que te gusta

Origin blog.csdn.net/weixin_47649808/article/details/126325560
Recomendado
Clasificación