Aprendizaje del rastreador (03): análisis de datos_re

1. Introducción al módulo re

1.1 re regularización

Regular Expression, expresión regular, una regla gramatical que usa expresiones para unir cadenas. Lo que
capturamos en la página web 页面源代码es esencialmente uno 超长的字符串. Si desea extraer contenido de ella, es 正则perfecto para usar.

Ventajas habituales:
速度快 效率高 准确性高
Sintaxis regular:
Utilice metacaracteres para permutaciones y combinaciones 匹配字符串 .

Metacaracteres comunes

 .     √匹配除换行符以外的任意字符,  未来在python的re模块中是一个坑. 
 \w    √匹配字母或数字或下划线.
 \s    匹配任意的空白符
 \d    √匹配数字
 \n    匹配一个换行符
 \t    匹配一个制表符
 
 ^     匹配字符串的开始
 $     匹配字符串的结尾
 
 \W    匹配非字母或数字或下划线
 \D    匹配非数字
 \S    匹配非空白符
 a|b   匹配字符a或字符b
 ()    √匹配括号内的表达式,也表示一个组
 [...]    √匹配字符组中的字符
 [^...]    匹配除了字符组中字符的所有字符

Cuantificador: controla el número de apariciones del metacarácter anterior.

 *    重复零次或更多次
 +    重复一次或更多次
 ?    重复零次或一次
 {n}    重复n次 
 {n,}    重复n次或更多次 
 {n,m}    重复n到m次

Emparejamiento codicioso y emparejamiento perezoso (énfasis)

 .*     贪婪匹配,  尽可能多的去匹配结果
 .*?    惰性匹配,  尽可能少的去匹配结果 -> 回溯

Banderas generales (modificador

valor ilustrar
re.I no distingue entre mayúsculas y minúsculas
re.M Coincidencia de varias líneas, que afecta a ^ y $
re.S hacer coincidir todos los caracteres, incluidas las nuevas líneas

1.2 re módulo

En el módulo re, solo necesitamos recordar las siguientes funciones para que las usemos.

1.2.1 función findall() (lista de retorno)

Escanea toda la cadena y devuelve una lista de cadenas de todos los resultados del patrón coincidente ( findall 查找所有. 返回list)
parámetro

parámetro ilustrar
pattern La expresión regular a coincidir (un patrón de cadenas)
string cadena para que coincida
flags Bit de identificación, utilizado para controlar el modo de coincidencia de la expresión regular.
import re
lst = re.findall("m", "mai le fo len, mai ni mei!") 
print(lst)    # ['m', 'm', 'm'] 
lst = re.findall(r"\d+", "5点之前. 你要给我5000万")
print(lst)   # ['5', '5000']

1.2.2 función de búsqueda ()

searchCoincidirá. Pero si coincide 第一个结果, devolverá este resultado. Si no coincide, searchdevolveráNone

import re
ret = re.search(r'\d', '5点之前. 你要给我5000万').group()
print(ret)  # 5

1.2.3 función de coincidencia ()

matchsolo de la cuerda开头进行匹配

ret = re.match('a', 'abc').group()  
print(ret)     # a

1.2.4 función buscador()

finditery findallmás o menos lo mismo Excepto que esto regresa 迭代器(énfasis agregado)

it = re.finditer("m", "mai le fo len, mai ni mei!")
for el in it:
    print(el.group()) # 依然需要分组

运行结果
inserte la descripción de la imagen aquí

1.2.5 función compilar ()

compile()Se puede realizar una expresión regular larga 预加载.后面的使用

obj = re.compile(r'\d{3}')  # 将正则表达式编译成为一个 正则表达式对象, 规则要匹配的是3个数字
ret = obj.search('abc123eeee') # 正则表达式对象调用search, 参数为待匹配的字符串
print(ret.group())  # 结果: 123

1.2.6 El contenido normal se extrae por separado

Para obtener el contenido específico en la expresión regular por separado, puede dar 分组起名字( ?P<name>xxx)

s = """
<div class='西游记'><span id='10010'>中国联通</span></div>
"""
obj = re.compile(r"<span id='(?P<id>\d+)'>(?P<name>\w+)</span>", re.S)

result = obj.search(s)
print(result.group())  # 结果: <span id='10010'>中国联通</span>
print(result.group("id"))  # 结果: 10010 # 获取id组的内容
print(result.group("name"))  # 结果: 中国联通 # 获取name组的内容

Aquí podemos ver que podemos usar 使用分组.para llevar a cabo aún más el contenido que coincide con la expresión regular 筛选.

1.2.7 Reemplazo de cuerdas

Las expresiones regulares se usan solas 提取字符串中的内容. También se pueden usar como字符串的替换

import re
r = re.split(r"\d+", "我今年19岁了, 你知道么, 19岁就已经很大了. 周杰伦20岁就得奖了")
print(r)  # ['我今年', '岁了, 你知道么, ', '岁就已经很大了. 周杰伦', '岁就得奖了']
# 替换
r = re.sub(r"\d+", "18", "我今年19岁了, 你知道么, 19岁就已经很大了. 周杰伦20岁就得奖了")
print(r)  # 我今年18岁了, 你知道么, 18岁就已经很大了. 周杰伦18岁就得奖了

​ Oh, normal, estas cosas son suficientes.

Dos, operación re práctica

2.1 La distinción entre codiciosos y no codiciosos

Podemos encontrar una regla de este tipo: .*?significa la menor cantidad de coincidencias posible .*y la mayor cantidad de coincidencias posible. Por el momento, recuerde esta regla primero. Se usará más adelante al escribir rastreadores.

str: 玩儿吃鸡游戏, 晚上一起上游戏, 干嘛呢? 打游戏啊
 reg: 玩儿.*?游戏
 
 此时匹配的是: 玩儿吃鸡游戏
 
 reg: 玩儿.*游戏   
 此时匹配的是: 玩儿吃鸡游戏, 晚上一起上游戏, 干嘛呢? 打游戏    
     
                 
 str: <div>胡辣汤</div>
 reg: <.*>
 结果: <div>胡辣汤</div>
 
 
 str: <div>胡辣汤</div>
 reg: <.*?>
 结果: 
     <div>
     </div>
 
 str: <div class="abc"><div>胡辣汤</div><div>饭团</div></div>
 reg: <div>.*?</div>
 结果:
     <div>胡辣汤</div>
	 <div>饭团</div>

2.2 Ejercicios con metacaracteres

[] 原子表
[a]  # 匹配a
[ab]  # 匹配a或者b
[abc]  # 匹配a或者b或者c
[123]  # 匹配1或者2或者3
[0-9]  # 匹配任意一位数字
[a-z]  # 匹配任意一位小写字母
[A-Z]  # 匹配任意一位大写字母
[a-zA-Z]  # 匹配任意大小写字母

[][]
[abc][0-9]  匹配a或者b或者c和任意一个数字->a1,b2,c3...

匹配手机号码
1[3-9][0-9]{
    
    9}  # {9} 代表前面的[0-9]9位 共11位

 ^ 限制开头 $ 限制结尾 一般用于组合
^1[3-9][0-9]{
    
    9}$  # 完全匹配 匹配的字符串中,必须完全符合才算匹配成功
13134534681  # 符合
131345346812 # 不符合 因为多了一位

{
    
    } 代表前面正则匹配的n词
[a-z]{
    
    2}  # 匹配两位小写字母
[a-z][a-z] # 等同于上方

{
    
    m,n} m-n之间的
[a-z]{
    
    2,5} # 匹配2-5个小写字母

 {
    
    m,} #至少匹配m个
[a-z]{
    
    2,} # 至少匹配2个小写字母

?可有可无
-?[1-9] # 匹配正负1-9

 . 匹配换行符以外的任意字符(不单独使用)
a   b   c  # 都能匹配

* 代表前面的0次或多次(不单独使用)

.*?组合 非贪婪匹配 (重要!!!) #匹配换行符以外的任意字符任意次

.*组合 贪婪匹配 #匹配换行符以外的任意字符任意次

 + 匹配一次到多次{
    
    1,}

.+? 非贪婪匹配 #匹配换行符以外的任意字符至少1次

| 代表或
[a-z]|[0-9] # 匹配字母或数字、

() #1. 作为一个单元  2. 作为子存储

2.3 ejercicios re modificadores

import re
#  re.I 是匹配队大小写不敏感
#  re.M 多行匹配,影响到^和$
#  re.S 使.匹配包括换行符在内的所有字符
mystr = """
<a href="http://www.baidu.com">百度</a>
<A href="http://www.baidu.com">百度</A>
<a href='http://www.sogou.com'>搜狗</a>
<a href="http://www.tengxun.com">腾
讯</a>
"""

# 首先匹配所有的正常a链接->小写
# print(re.findall("<a href=\"http://www.baidu.com\">百度</a>")) #内部用转义
print(re.findall('<a href="(.*?)">(.*?)</a>', mystr))  # 外部用单引号
# 可以发现,只能匹配出一个结果来
# >>>[('http://www.baidu.com', '百度')]

# re.I 不区分大小写
print(re.findall('<a href="(.*?)">(.*?)</a>', mystr, re.I))
# 可以发现,匹配出两个结果来了
# >>>[('http://www.baidu.com', '百度'), ('http://www.baidu.com', '百度')]

#  匹配大小写 多行匹配 可以匹配换行符 中间用|隔开
print(re.findall('<a href="(.*?)">(.*?)</a>', mystr, re.I | re.M | re.S))
# >>> [('http://www.baidu.com', '百度'), ('http://www.baidu.com', '百度'), ('http://www.tengxun.com', '腾\n讯')]
# 可以发现匹配出来了三个结果,但唯独少一个搜狗,因为搜狗是用单引号扩起来的

# 在上面的案例基础上匹配单双引号 [] 表示或,表示双引号或者单引号
print(re.findall('<a href=[\'"](.*?)[\'"]>(.*?)</a>', mystr, re.I | re.M | re.S))
# >>> 匹配出来了全部结果
print('*'*20)
myStr = """asadasdd1\nbsadasdd2\ncsadasdd3"""
print(re.findall('^[a-z]',myStr))  # 匹配以字母开头
# >>> ['a']
print(re.findall('\A[a-z]',myStr))  # 匹配以字母开头 (整段)
# >>> ['a']
print(re.findall('\d$',myStr))  # 匹配以数字结尾
# >>> ['3']
print(re.findall('\d\Z',myStr))  # 匹配以数字结尾 (整段)
# >>> ['3']

# re.M
print(re.findall('^[a-z]',myStr, flags=re.M))
# >>> ['a', 'b', 'c']
print(re.findall('\A[a-z]',myStr, flags=re.M))
# >>> ['a']
print(re.findall('\d$',myStr, flags=re.M))
# >>> ['1', '2', '3']
print(re.findall('\d\Z',myStr, flags=re.M))
# >>> ['3']

2.4 ejercicio match_search_findall

import re

# r"" 专业写正则,没有转义的烦恼

# search re.search(正则,字符串) 会进行匹配. 但是如果匹配到了第一个结果. 就会返回这个结果. 如果匹配不上search返回的则是None
print('search')
print()
print(re.search(r'a', '123456'))  # None
# group() 若匹配成功则返回匹配数值
print(re.search(r'[a-z]','123c423').group())  # c
print(re.search(r'[a-z][a-z]', '12321a21'))  # None
print(re.search(r'1[3-9][0-9]{9}','1345643256543').group())  # 13456432565
print(re.search(r'1[3-9][0-9]{9}','b1345643256543b').group())  # 13456432565
print(re.search(r'^1[3-9][0-9]{9}','x1345643256543'))  # None

print('-'*30)
print('match')
print()
# match 只匹配一次,必须从第一位开始,类似于search('^')
print(re.match(r'a','a213131').group())  # a
print(re.match(r'a','213131'))  # None
print(re.match(r'[a-z]','123x456'))  # None
print(re.match(r'1[1-3][0-9]{9}','b1345643256543b'))  # None
print(re.match(r'1[1-3][0-9]{9}','1345643256543b').group())  # 1345643256543

print('-'*30)
print('findall')
# 查找所有 结果返回列表
print(re.findall(r"\d+","我有1000万,不给你话,给你1块钱拿去"))  # ['1000', '1']

3. Acerca del resumen

  1. .*?-> coincidencia perezosa / *-> coincidencia codiciosa
  2. searce()Función: escanea toda la cadena y devuelve 第一个la coincidencia exitosa del patrón y regresa si la coincidencia fallaNone
  3. findall()函数Escanea toda la cadena y devuelve una lista de cadenas de todos los resultados de patrones coincidentes.
  4. match()函数Si la coincidencia tiene éxito, se devolverá el objeto coincidente
    ; si la coincidencia falla, se devolverá el objetoNone
  5. reEl mejor 常用lugar -> Obtener uno de js en html 部分代码(en cadena)

Supongo que te gusta

Origin blog.csdn.net/m0_48936146/article/details/127308765
Recomendado
Clasificación