Python小知识-正则表达式和Re库(二)

本文深入探讨Python正则表达式的高级应用,包括search()、findall()、sub()和compile()函数的使用技巧,旨在帮助读者掌握复杂文本处理与信息提取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原创不易,转载前请注明博主的链接地址:Blessy_Zhu https://blog.youkuaiyun.com/weixin_42555080
本次代码的环境:
运行平台: Windows
Python版本: Python3.x
IDE: PyCharm

1 概述

上一篇文章Python小知识-正则表达式和Re库(一)讲解了正则表达式的基本内容,包括介绍了一个正则表达式的测试工具、介绍了常用的匹配规则、介绍了一个最基本、最终重要的函数match()、;匹配目标中的group()和span()方法、通用匹配.* 、贪婪和非贪婪 .*和. * ?、修饰符re.S、转义匹配等内容,这篇文章会继续讲解search()函数、findall()函数、sub()函数、compile()函数。闲话少说,直奔主题…


在这里插入图片描述

2 search()函数

上一篇文章Python小知识-正则表达式和Re库(一)讲到的match()方法是从字符串的开头开始匹配的,那么这就会遇到一个问题,一旦开头匹配不成功,那么整个匹配就会失败。比如下面这这个例子:

import re

content = 'My phone number is 15238887777 Hello 1234567 zoneNumber I came from Laifeng in Hubei Enshi'
result = re.match("Hello.*?(\d+).*?Enshi",content)
print(result)
print(result.group(1))

这里面的字符串是以“My phone number is 15238887777”开头的,但是正则表达式则是以Hello开头,整个正则表达式是字符串的一部分,但是这样的匹配是失败的,运行结果是:
None
Traceback (most recent call last):
File “C:/Users/Administrator/PycharmProjects/practice1/buffer1.py”, line 7, in
print(result.group(1))
AttributeError: ‘NoneType’ object has no attribute ‘group’

这是因为match()函数在使用时需要考虑到开头的内容,这在做匹配时并不方便。match()更适合用来检测某个字符串是否符合某个正则表达式的规则。
这时候就需要另外一个方法search(),它在匹配时会扫描整个字符串,然后返回第一个成功匹配的结果。也就是说,正则表达式可以是字符串的一部分, 在匹配时,search()方法会依次扫描字符串,有到找到第个符合规则的字符串, 然后返回匹配内容, 如果搜索完了还没有找到, 就返回None。把上面代码中的match()方法修改成search(),再看下运行结果:
<re.Match object; span=(31, 90), match='Hello 1234567 zoneNumber I came from Laifeng in H>1234567
这时就得到了匹配结果。因此,为了匹配方便,我们可以尽量使用search()方法。接下里再举一个例子,我们用search()方法匹配如图1所示猫眼电影排行Top100的列表,在此只涉及一个片段内容的提取。


在这里插入图片描述
图1

import re

content = '''  
<dd>
   <i class="board-index board-index-1">1</i>
   <a href="/films/1203" title="霸王别姬" class="image-link" data-act="boarditem-click" data-val="{movieId:1203}">
   <img src="//s0.meituan.net/bs/?f=myfe/mywww:/image/loading_2.e3d934bf.png" alt="" class="poster-default" />
   <img data-src="https://p1.meituan.net/movie/20803f59291c47e1e116c11963ce019e68711.jpg@160w_220h_1e_1c" alt="霸王别姬" class="board-img" />
   </a>
   <div class="board-item-main">
     <div class="board-item-content">
     <div class="movie-item-info">
       <p class="name"><a href="/films/1203" title="霸王别姬" data-act="boarditem-click" data-val="{movieId:1203}">霸王别姬</a></p>
       <p class="star">
               主演:张国荣,张丰毅,巩俐
       </p>
       <p class="releasetime">上映时间:1993-01-01</p>    
     </div>
     <div class="movie-item-number score-num">
       <p class="score"><i class="integer">9.</i><i class="fraction">6</i></p>        
     </div>
     </div>
   </div>
</dd>'''
result = re.search('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a'
                        + '.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>'
                        + '.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>',content,re.S)
print(result)
print(result.group(1))
print(result.group(2))
print(result.group(3))
print(result.group(4).strip())
print(result.group(5))
print(result.group(6))
print(result.group(7))

结果分别获得电影的猫眼电影排行名词、图片地址、影片名字、主演、上映时间、评分整数部分、评分小数部分,如图2所示:


在这里插入图片描述图2

这段代码较为简单,其中content是截取的HTML片段,search()里面是一个正则表达式。在这里可以直接讲解正则表达式:通过上面的HTML可以看到,它是以dd标签开头的,然后通配符,遇到匹配到board-index.*?找到后面呢标明序号的数字(即排行名词)。接着匹配名字,这个例子特别讲,后面就和它一样了,就不在细讲了:首先看HTML源码如图3:


在这里插入图片描述图3

接下来要匹配的内容就是画红框框部分的内容,可以看到它这个的是在p标签内,首先定位唯一标志符p标签内的class属性的“name”值 name"><a’,唯一定位完毕后实现通配.?,然后确定读取位置是在>XXX标签内,通过匹配目标()进行提取定位,完整的正则表达式匹配代码是name"><a’ + '.?>(.*?),这样就完成了。其他的代码类似,可参考此内容带入。

3 findall()函数

前面介绍了search()方法的用法,它可以返回匹配正则表达式的第个内容, 但是如果想要本敢匹配正则表达式的所有内容,那该怎么办呢?这时就要借助findall()方法了 。该方法会搜索整个字符串,然后返回匹配正则表达式的所有内容。还是上面的HTML文本,如果想获取所有a节点的超链接、歌手和歌名,就可以将search()方法掉成findall()方法。如果有返回结果的话,就是列表类型,所以需要遍历一下来依次获取每组内容。代码如下:

import re

content = '''  
<dd>
   <i class="board-index board-index-1">1</i>
   <a href="/films/1203" title="霸王别姬" class="image-link" data-act="boarditem-click" data-val="{movieId:1203}">
   <img src="//s0.meituan.net/bs/?f=myfe/mywww:/image/loading_2.e3d934bf.png" alt="" class="poster-default" />
   <img data-src="https://p1.meituan.net/movie/20803f59291c47e1e116c11963ce019e68711.jpg@160w_220h_1e_1c" alt="霸王别姬" class="board-img" />
   </a>
   <div class="board-item-main">
     <div class="board-item-content">
     <div class="movie-item-info">
       <p class="name"><a href="/films/1203" title="霸王别姬" data-act="boarditem-click" data-val="{movieId:1203}">霸王别姬</a></p>
       <p class="star">
               主演:张国荣,张丰毅,巩俐
       </p>
       <p class="releasetime">上映时间:1993-01-01</p>    
     </div>
     <div class="movie-item-number score-num">
       <p class="score"><i class="integer">9.</i><i class="fraction">6</i></p>        
     </div>
     </div>
   </div>
</dd>
<dd>
   <i class="board-index board-index-2">2</i>
   <a href="/films/1297" title="肖申克的救赎" class="image-link" data-act="boarditem-click" data-val="{movieId:1297}">
   <img src="//s0.meituan.net/bs/?f=myfe/mywww:/image/loading_2.e3d934bf.png" alt="" class="poster-default" />
   <img data-src="https://p0.meituan.net/movie/283292171619cdfd5b240c8fd093f1eb255670.jpg@160w_220h_1e_1c" alt="肖申克的救赎" class="board-img" />
   </a>
   <div class="board-item-main">
   <div class="board-item-content">
   <div class="movie-item-info">
       <p class="name"><a href="/films/1297" title="肖申克的救赎" data-act="boarditem-click" data-val="{movieId:1297}">肖申克的救赎</a></p>
       <p class="star">
               主演:蒂姆·罗宾斯,摩根·弗里曼,鲍勃·冈顿
       </p>
       <p class="releasetime">上映时间:1994-10-14(美国)</p>    
   </div>
   <div class="movie-item-number score-num">
    <p class="score"><i class="integer">9.</i><i class="fraction">5</i></p>        
   </div>
   </div>
   </div>
</dd>
'''
results = re.findall('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a'
                        + '.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>'
                        + '.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>',content,re.S)
for result in results:
   print(result[0],result[1],result[2],result[3].strip(),result[4],result[5],result[6])

这个代码中的content里面有两个以dd换位findall()函数后,匹配的内容应该是两条,打印后的结果如下:
1 https://p1.meituan.net/movie/20803f59291c47e1e116c11963ce019e68711.jpg@160w_220h_1e_1c 霸王别姬 主演:张国荣,张丰毅,巩俐 上映时间:1993-01-01 9. 6
2 https://p0.meituan.net/movie/283292171619cdfd5b240c8fd093f1eb255670.jpg@160w_220h_1e_1c 肖申克的救赎 主演:蒂姆·罗宾斯,摩根·弗里曼,鲍勃·冈顿 上映时间:1994-10-14(美国) 9. 5

4 sub()函数

除了使用正则表达式提取信息外,有时候还需要借助它来修改文本。比如,想要去掉文本中的所有数字,如果通过字符串的replace()方法,那就太烦琐了,这时可以借助sub()方法。示例如下:

import re

content = '123hello 888 i am 55 Blessy'
content = re.sub('\d+', '', content)
print(content)

运行结果如下:hello i am Blessy
sub(‘去掉的内容’,‘替换的内容’,‘原文本内容’)这里只需要给第一个参数传入\d来匹配所有的数字,第二个参数未替换的字符串,第三个参数是原字符串。

5 compile()函数

match()、search()、findall()这些函数都是用来处理字符串的方法,最后再介绍一下compile()方法这个方法可以将正则字符串编译成正则表达式对象, 以便在后面的匹配中复用, 示例代码如下:

import  re

content1=' 2016-12-15 12:00'
content2 ='2016-12-17 12:55 '
content3=' 2016-12-22 13:21 '
pattern = re.compile('\d{2}:\d{2}')
result1 = re.sub(pattern,'', content1)
result2 = re.sub(pattern, '', content2)
result3 = re.sub(pattern,'' , content3)
print(result1, result2, result3)

通过这个代码可以看到,它是现将正则表达式’\d{2}:\d{2}’(这个正则表达式的含义是:匹配:及:前后各2各数字),编译成正则表达式对象,通过sub将时间部分去掉。结果就是:
2016-12-15 2016-12-17 2016-12-22
re模块中这个重要函数是compile(pattern [, flags]) ,该函数根据包含的正则表达式的字符串创建模式对象。可以实现更有效率的匹配。在直接使用字符串表示的正则表达式进行search(),match()和findall()操作时,python会将字符串转换为正则表达式对象。而使用compile()完成一次转换之后,再每次使用模式的时候就不用重复转换。使用re.compile()函数进行转换后,re.search(pattern, string)的调用方式就转换为 pattern.search(string)的调用方式,当然前者的调用方式也可以继续使用

总结

这篇内容讲解了正则表达式的基本内容,包括解search()函数、findall()函数、sub()函数、compile()函数。作为上一篇文章Python小知识-正则表达式和Re库(一)的姊妹篇,通过这两篇文章就全部讲解了正则表达式的全部内容以及re库对应的全部内容。以上内容参考资料:崔庆才《Python3 网络爬虫开发实战》,夏敏捷《Python程序设计-从基础到开发》,[挪]芒努斯·利·海特兰德(Magnus Lie Hetland)《Python基础教程第3版 Python编程从入门到实践 》,并对以上作者表示感谢。这篇文章就到这里了,欢迎大佬们多批评指正,也欢迎大家积极评论多多交流。
 

 
  在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值