常见匹配模式

模式描述
w匹配字母及下划线
W匹配非字母数字及下划线
s匹配任意空白字符,等价于[tnrf]
S匹配任意非空字符
D匹配任意数字,等价于[0-9]
A匹配任意非数字
Z匹配字符串开始
z匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串
G匹配最后匹配完成的位置
n匹配一个换行符
t匹配一个制表符
^匹配字符串的开头
$匹配字符串的末尾
.匹配任意字符,除了换行符,当re.DOTALL标记被制定时,则可以匹配包括换行符的任意字符
[...]用来表示一组字符串,单独列出:[amk]匹配'a','m','k'
[^...]不在[]中的字符,[^abc]匹配除了'a','b','c'之外的字符
*匹配0个或多个的表达式
+匹配1个或多个的表达式
?匹配0个或1个由前面的正则表达式的片段,非贪婪方式
{n}精确匹配n一个前面的表达式,
{n,m}匹配n到m次由前面的正则表达式定义的片断,贪婪方式
a|b匹配a或b
()匹配括号内的表达式,也表示一个组

re.match

基本匹配

import re

content = 'Hello 123 4567 word_this is a Regex Demo'

res = re.match(r'^Hello\s\d{3}\s\d{4}\s\w{9}',content)
print(res)
print(res.group())
print(res.span())

==========返回结果==========

<re.Match object; span=(0, 24), match='Hello 123 4567 word_this'>
Hello 123 4567 word_this
(0, 24)

泛匹配

使用.*可以匹配任意字符

import re

content = 'Hello 123 4567 word_this is a Regex Demo'

res = re.match(r'^Hello.*Regex',content)
print(res)
print(res.group())
print(res.span())

==========返回结果==========

<re.Match object; span=(0, 35), match='Hello 123 4567 word_this is a Regex'>
Hello 123 4567 word_this is a Regex
(0, 35)

目标匹配

如果正则表达式中出现了括号,group(1) 就代表第一个括号中的内容,以此类推

import re

content = 'Hello 1234567 World_This is a Regex Demo'
res = re.match(r'^Hello\s(\d+)\sWorld.*Demo$',content)
print(res)
print(res.group(1))
print(res.span())

==========返回结果==========

<re.Match object; span=(0, 40), match='Hello 1234567 World_This is a Regex Demo'>
1234567
(0, 40)

贪婪匹配

.* 默认为贪婪匹配,即尽可能多的匹配字符

import re

content = 'Hello 1234567 World_This is a Regex Demo'
res = re.match(r'^He.*(\d+).*Demo$',content)
print(res)
print(res.group(1))
print(res.span())

==========返回结果==========

<re.Match object; span=(0, 40), match='Hello 1234567 World_This is a Regex Demo'>
7
(0, 40)

非贪婪匹配

使用?为非贪婪匹配,即尽可能少的匹配字符

import re

content = 'Hello 1234567 World_This is a Regex Demo'
res = re.match(r'^He.*?(\d+).*Demo$',content)
print(res)
print(res.group(1))
print(res.span())

==========返回结果==========

<re.Match object; span=(0, 40), match='Hello 1234567 World_This is a Regex Demo'>
1234567
(0, 40)

匹配模式

.* 是不包含换行符的,在re.match()函数中使用re.S参数指定匹配模式,可正常匹配换行符

import re

content = '''Hello 1234567 World_This 
is a Regex Demo
'''
res = re.match(r'^He.*?(\d+).*Demo$',content,re.S)
print(res)
print(res.group(1))
print(res.span())

==========返回结果==========

<re.Match object; span=(0, 41), match='Hello 1234567 World_This \nis a Regex Demo'>
1234567
(0, 41)

转义字符

字符串中含有 . $ 等特殊字符时,在正则表达式中使用 \ 进行转义

import re

content = 'price is $5.00'
res = re.match(r'price is \$\d\.\d{2}$',content)
print(res)

==========返回结果==========

<re.Match object; span=(0, 14), match='price is $5.00'>

尽量使用泛匹配、使用括号得到匹配目标、尽量使用非贪婪模式、有换行符就用 re.S

re.search

re.match 如果第一个字符无法匹配,则匹配失败

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

import re

content = 'Extra String Hello 1234567 World_This is a Regex Demo Extra String'
res = re.search(r'Hello.*?(\d+).*?is',content)
print(res)
print(res.group(1))

==========返回结果==========

<re.Match object; span=(13, 37), match='Hello 1234567 World_This'>
1234567

为匹配方便,尽量使用re.search函数

re.findall

搜索字符串,以列表的形式返回全部能匹配的字符串

抓取电影天堂欧美电影列表页的标题,网页如下

已知标题在 <a></a> 在标签内,且被 《》 包裹

import re,requests

response = requests.get('http://www.dytt8.net/html/gndy/oumei/index.html')
response.encoding = 'gb2312'
html = response.text

result = re.findall(r'<a.*?class="ulink".*?《(.*?)》.*?◎片\s名\s(.*?)◎',html,re.S)
for item in result:
    print(item[0],item[1])

==========返回结果==========

地狱铁匠 Errementari / Errementari: The Blacksmith and the Devil 
抱歉打扰 Sorry to Bother You 
丘吉尔 Churchill/Warlord 
瘦长鬼影 Slender Man 
敬畏/情陷高达 Le Redoutable / Redoubtable / Godard Mon Amour 
孪生陌生人 Three Identical Strangers 
最终行动 Operation Finale/Eichmann 
幸运是她 Fortunata 
蚁人2:黄蜂女现身 Ant-Man and the Wasp 
解除好友2:暗网 Unfriended: Dark Web 
监控惊魂 14 Cameras 
以吻之名 With a Kiss I Die 
过境/时空中转站 Transit 
妈妈咪呀2:再次出发 Mamma Mia! Here We Go Again 
使徒 Apostle 
镜中人 Look Away 
卧底 Buybust 
莫莉 Molly 
下层人 Lowlife 
花神 Flora 
世界之间 Between Worlds 
康斯坦丁:恶魔之城 Constantine: City of Demons 
贾斯珀・琼斯 Jasper Jones 
等待指示 Await Further Instructions 
阿尔忒弥斯酒店 Hotel Artemis 

re.sub

可以对字符串使用正则表达式指定的部分进行替换

常用方法为把多余的html结构替换为空,达到数据清洗的目的

import re

content = 'Extra strings Hello 123456 World_This is a Regex Demo Extra strings'
content_new = re.sub('\d+','',content) #第二个参数为替换内容,留空
print(content_new)

==========返回结果==========

Extra strings Hello  World_This is a Regex Demo Extra strings

re.compile

将正则表达式封装为对象,成为一个匹配模式,则该匹配模式可重复使用

import re

content1 = '''Extra strings Hello 123456 World_This 
is a Regex Demo Extra strings'''
pattern = re.compile(r'.*?(\d+).*?',re.S)
result = re.findall(pattern,content1) #pattern做为匹配模式可重复使用
print(result[0])
print(type(result))

==========返回结果==========

123456
<class 'list'>