python爬虫(五)正则表达式

正则表达式:

在这里插入图片描述
有了正则表达式,对于从html中提取想要的信息就不在话下了。

常见的匹配规则:

在这里插入图片描述
\d:匹配任意数字
^:匹配一行字符串的开头
$:匹配以后字符串的结尾
. :匹配任意字符,除了换行符
+:匹配1个或多个表达式
*:匹配1个或多个表达式

python re库

对于python re库提供了整个正则表达式的实现

match()方法:

利用此方法,传入匹配的字符串以及正则表达式,便可以检测这个正则表达式是否匹配字符串

import re
content="Hello 123 4567 World_This is a Regex Demo"
result=re.match('^Hello\s\d{3}\s\d{4}\s\w{10}',content)
print(result)# SRE_Match对象,若返回此对象,则说明匹配成功
print(result.group())#group可以输入匹配到的内容
print(result.span())#输出匹配的范围
匹配目标

match方法可以匹配到字符串,如果想从字符串中提取一部分内容,就需要用到()表示提取想要的那一部分字符串,()实际上标记了一个子表达式的开头和结尾,在通过调用group(参数)方法来提取结果

import re
content="Hello 1234567 World_This is a Regex Demo"
result=re.match('^Hello\s(\d+)\sWorld',content)
print(result)# SRE_Match对象,若返回此对象,则说明匹配成功
print(result.group())#group可以输入匹配到的内容
print(result.group(1))#输入想要的数字
print(result.span())#输出匹配的范围
通用匹配

上述我们写的正则表达式过于复杂,为了简化我们的工作量,于是我们可以用==.* (点星)==,其中点可以匹配任意字符(除换行符),星(*)代表匹配前面的字符无限次,所以主合起来就可以匹配任意字符了

import re
content="Hello 123 4567 World_This is a Regex Demo"
result=re.match('^Hello.*Demo$',content)
print(result)# SRE_Match对象,若返回此对象,则说明匹配成功
print(result.group())#group可以输入匹配到的内容
print(result.span())#输出匹配的范围
贪婪与非贪婪
import re
content="Hello 1234567 World_This is a Regex Demo"
result=re.match('^He.*(\d+).*Demo$',content)
print(result)# SRE_Match对象,若返回此对象,则说明匹配成功
print(result.group(1))#最后输入来的结果为7

对与上述代码,我们本意想要获得1234567,可是结果却给我们了一个7,在贪婪匹配下,.*会尽可能多的匹配字符,,而\d+也就是至少有一个数字,并没有具体指出有多少,因此就把123456匹配进去了,,因此就得到了7,也就可以满足\d+这个条件。

在这里插入图片描述

因此我们可以通过非贪婪匹配 (.*?)

非贪婪匹配就是尽可能少的匹配字符,

import re
content="Hello 1234567 World_This is a Regex Demo"
result=re.match('^He.*?(\d+).*Demo$',content)
print(result)# SRE_Match对象,若返回此对象,则说明匹配成功
print(result.group(1))#最后输入来的结果为1234567

解释:.?匹配到Hello后面的空白字符时,在往后就是数字了,而\d+正好可以匹配,因此.?就不再匹配,交给\d+去处理后面的数字,所以就得到了1234567

在做匹配的时候,尽可能使用非贪婪匹配,以免出现缺失的情况

修饰符:
import re
content='''Hello 1234567 World_This 
is a Regex Demo'''
result=re.match('^He.*?(\d+).*Demo$',content)
print(result)# SRE_Match对象,若返回此对象,则说明匹配成功
print(result.group(1))

在这里插入图片描述
我们可以发现,content只是加了一个换行符,但由于.只能匹配除换行符以为的字符,所以.?就不可以匹配了。这时我们紧需要一个参数,re.S修正错误即可

import re
content='''Hello 1234567 World_This 
is a Regex Demo'''
result=re.match('^He.*?(\d+).*Demo$',content,re.S)
print(result)# SRE_Match对象,若返回此对象,则说明匹配成功
print(result.group(1))#最后输入来的结果为1234567

这里补充一下,修饰符
re.l :使匹配大小写不敏感
re.S:匹配包括换行在内的所有字符
…后面就自行查阅百度吧

转移匹配
import re
content='price is $5.00'
result=re.match('price is $5.00',content)
print(result)
#会打印出none

import re
content='price is $5.00'
result=re.match('price is \$5\.00',content)
print(result)
#<re.Match object; span=(0, 14), match='price is $5.00'>

当正则匹配模式遇到特俗字符时,只需要加反斜杠转义即可

re.search方法:扫描整个字符串并返回第一个成功的匹配

前面我们说过match方法时从字符串的开头开始匹配的,一旦不是从开头,就会匹配失败


import re
content='Extra strings Hello 1234567 World_This is a Regex Demo'
result=re.search('^Hello.*?(\d+).*?Demo',content)
print(result)
print(result.group(1))

```总结:为匹配方便,能使用search就不用match
#  实战:

```python
import re
html='''<div id="song-list">
<h2 class="title">经典老歌</h2>
<p class="introduction">
经典老歌列表
</p>
<ul id="list" class="list-group">
<li data-view="2">一路有你</li>
<li data-view="7">
<a href="/2.mp3" singer="任贤齐">沧海一笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="秦齐">往事随风</a>
</li>
<li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
<li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li>
<li data-view="5">
<a href="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>'''
result=re.search('<li.*?active.?singer="(.*?)">(.*?)</a>',html,re.S)
if result:
    print(result.group(1),result.group(2))

结果为:往事随风

findall()

search可以返回匹配正则表达式的第一个内容,但是如果想要获取匹配正则表达式的所有内容,就需要用到findall了

import re
html='''<div id="song-list">
<h2 class="title">经典老歌</h2>
<p class="introduction">
经典老歌列表
</p>
<ul id="list" class="list-group">
<li data-view="2">一路有你</li>
<li data-view="7">
<a href="/2.mp3" singer="任贤齐">沧海一笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="秦齐">往事随风</a>
</li>
<li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
<li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li>
<li data-view="5">
<a href="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>'''
result=re.search('<li.*?active.?singer="(.*?)">(.*?)</a>',html,re.S)
if result:
    print(result.group(1),result.group(2))

2

import re
html='''<div id="song-list">
<h2 class="title">经典老歌</h2>
<p class="introduction">
经典老歌列表
</p>
<ul id="list" class="list-group">
<li data-view="2">一路有你</li>
<li data-view="7">
<a href="/2.mp3" singer="任贤齐">沧海一笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="秦齐">往事随风</a>
</li>
<li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
<li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li>
<li data-view="5">
<a href="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>'''
results=re.findall('<li.*?href="(.*?)".*?singer="(.*?)">(.*?)</a>',html.re.S)
print(results)

re.sub:替换字符串中没每一个匹配的字符串后返回替换后的字符串

import re
content='Extra strings Hello 1234567 World_This is a Regex Demo' 
conntent=re.sub('\d+','',content)
print(content)

import re
content='Extra strings Hello 1234567 World_This is a Regex Demo' 
conntent=re.sub('\d+','Replacement',content)
print(content)

re.compile 将正则字符串编译成正则表达式对象,以便重用该匹配模式

import re
content='"Hello 1234567 World_This
is a Regex Demo'"
pattern=re.compile('Hello.*Demo',re.S)
result=re.match(pattern,content)
print(result) 
发布了63 篇原创文章 · 获赞 12 · 访问量 4050

猜你喜欢

转载自blog.csdn.net/qq_45353823/article/details/104203791
今日推荐