详解Python3中的正则表达式的基本用法(5)

因为我们把active标签去掉之后,从字符串开头开始搜索,符合条件的节点就变成了第二个<li>节点,后面的就不再进行匹配,所以运行结果自然就变成了第二个<li>节点中的内容。

注意在上面两次匹配中,search()方法的第三个参数我们都加了re.S,使得.*?可以匹配换行,所以含有换行的<li>节点被匹配到了,如果我们将其去掉,结果会是什么?

reresult = re.search('<li.*?singer="(.*?)">(.*?)</a>', html) if result: print(result.group(1), result.group(2))

运行结果: 

beyond 光辉岁月

可以看到结果就变成了第四个<li>节点的内容,这是因为第二个和第三个<li>标签都包含了换行符,去掉re.S之后,.*?已经不能匹配换行符,所以正则表达式不会匹配到第二个和第三个<li>节点,而第四个<li>节点中不包含换行符,所以成功匹配。

由于绝大部分的HTML文本都包含了换行符,所以通过上面的例子,我们尽量都需要加上re.S修饰符,以免出现匹配不到的问题。

findall()

在前面我们说了search()方法的用法,它可以返回匹配正则表达式的第一个内容,但是如果我们想要获取匹配正则表达式的所有内容的话怎么办?这时就需要借助于findall()方法了。

findall()方法会搜索整个字符串然后返回匹配正则表达式的所有内容。

还是上面的HTML文本,如果我们想获取所有节点的超链接、歌手和歌名,就可以将search()方法换成findall()方法。如果有返回结果的话就是list类型,所以我们需要遍历一下list来获依次获取每组内容。

reresults = re.findall('<li.*?href="https://ask.hellobi.com/(.*?)".*?singer="(.*?)">(.*?)</a>', html, re.S) print(results) print(type(results)) for result in results: print(result) print(result[0], result[1], result[2])

运行结果:

[('https://www.jb51.net/2.mp3', '任贤齐', '沧海一声笑'), ('https://www.jb51.net/3.mp3', '齐秦', '往事随风'), ('https://www.jb51.net/4.mp3', 'beyond', '光辉岁月'), ('https://www.jb51.net/5.mp3', '陈慧琳', '记事本'), ('https://www.jb51.net/6.mp3', '邓丽君', '但愿人长久')] 
<class 'list'> 
('https://www.jb51.net/2.mp3', '任贤齐', '沧海一声笑') 
/2.mp3 任贤齐 沧海一声笑 
('https://www.jb51.net/3.mp3', '齐秦', '往事随风') 
/3.mp3 齐秦 往事随风 
('https://www.jb51.net/4.mp3', 'beyond', '光辉岁月') 
/4.mp3 beyond 光辉岁月 
('https://www.jb51.net/5.mp3', '陈慧琳', '记事本') 
/5.mp3 陈慧琳 记事本 
('https://www.jb51.net/6.mp3', '邓丽君', '但愿人长久') 
/6.mp3 邓丽君 但愿人长久

可以看到,返回的list的每个元素都是tuple类型,我们用对应的索引依次取出即可。

所以,如果只是获取第一个内容,可以用search()方法,当需要提取多个内容时,就可以用findall()方法。

sub()

正则表达式除了提取信息,我们有时候还需要借助于它来修改文本,比如我们想要把一串文本中的所有数字都去掉,如果我们只用字符串的replace()方法那就太繁琐了,在这里我们就可以借助于sub()方法。

我们用一个实例来感受一下:

import re content = '54aK54yr5oiR54ix5L2g' content = re.sub('\d+', '', content) print(content)

运行结果: 

aKyroiRixLg

在这里我们只需要在第一个参数传入d+来匹配所有的数字,然后第二个参数是替换成的字符串,要去掉的话就可以赋值为空,第三个参数就是原字符串。

得到的结果就是替换修改之后的内容。

那么在上面的HTML文本中,如果我们想正则获取所有<li>节点的歌名,如果直接用正则表达式来提取可能比较繁琐,比如可以写成这样子:

reresults = re.findall('<li.*?>\s*?(<a.*?>)?(\w+)(</a>)?\s*?</li>', html, re.S) for result in results: print(result[1])

运行结果: 

一路上有你 
沧海一声笑 
往事随风 
光辉岁月 
记事本 
但愿人长久

但如果我们借助于sub()函数就比较简单了,我们可以先用sub()函数将节点去掉,只留下文本,然后再利用findall()提取就好了。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjxjff.html