目录
- 正则简介
-
- 正则表达函数
-
- match函数
- search函数
- 正则匹配符号
-
- 元字符
- 字符匹配符号
- 范围匹配符号
-
- 案例一:字符匹配的范围控制
- 数量匹配符号
-
- 案例二:字符匹配的数量控制
- 简化正则表达式
- 正则表达式中的逻辑符
-
- 案例三:多个示例正则表达式
- 正则匹配模式
- 分组
-
- 分组正则表达式
- 正则分组函数
-
- 案例四:利用分组匹配日期
- 实际运用
-
- re模块一般使用步骤
- re模块使用两种形式
-
-
- 案例一:豆瓣250部分网页源码
- 案例二:获取中国大学MOOC学校列表
-
正则简介
可能用到的网站
- oschina开源中国
正则表达式是一种由特殊符号组成的序列,可以用于检查某一个字符串是否与某种结构匹配# 基础知识
正则表达函数
正则表达式并不是python的原生语法,python中使用正则表达式必须依靠re模块,下面介绍一些re模块中的常用函数
函数 | 描述 | 返回结果 |
---|---|---|
compile(pattern[,flags]) |
将正则表达式转化为一个正则表达式对象,flags用于指定正则匹配模式,如re.S) | pattern对象 |
findall(pattern,str[,flags]) |
匹配所有符合条件的文本 | 列表形式 |
finditer(pattern,str[,flags]) |
匹配所有符合条件的文本 | 迭代对象(Match对象) |
match(pattern,str[,flags]) |
从头开始匹配 | 一个Match类对象 |
search(pattern,str[,flags]) |
从任意位置开始匹配 | 一个Match类对象 |
sub(pattern,repl,string[,count,flags]) |
正则匹配替换,count表示替换次数(默认全部替换,并不改变原字符串) | 原字符串的拷贝并替换 |
subn(pattrn,repl,string[count,flags]) |
正则匹配替换,并返回替换结果 | |
split(pattern,str[,maxsplit,flags]) |
按给定匹配符号拆分字符串 |
正则表达式的使用示例见下文:re模块使用的两种形式,下面介绍match()和search()函数
match函数
match函数会从一个字符串开头开始匹配,匹配成功则返回一个Match类的对象,
search函数
search函数可以c从一个字符串中的任意位置开始匹配,同时也会返回匹配结果的索引值
正则匹配符号
元字符
字符 | 描述 | 正则表达式举例 |
---|---|---|
^ | 匹配一行字符串的开始位置 或取反 | ^http :表示匹配所有以‘http’开头的字符串 |
$ | 匹配一行字符串的结束位置 | |
| | 选择符号,表示或 | python\|pycharm :表示可以匹配python或pycharm |
. | 匹配除换行符外的任意一个字符 | |
{} | 大括号中加n表示重复次数(如{10}表示重复10次) | (python){3} :表示一段包含三个“python”的字符串 |
[] | 一个字符集,表示匹配其中的某个;中括号中的“-”表示连续(如[0-9]表示0到9) | [cij]python :表示可以匹配”cpython”,“ipython”,“jpython” |
() | 表示分组或括起来表示子表达式 | (a\|b)*c :表示匹配0个1个或多个a或b,后面紧跟字母c |
字符匹配符号
正则是一组特殊符号的应用,下面介绍常用的正则符号
符号 | 描述 |
---|---|
x | 匹配任意一位字符 |
\ | 匹配转义字符 |
\t | 制表符 |
\n | 换行符 |
\r | 匹配转义字符 |
进行单个字符匹配,要匹配的字符串必须与单个字符的内容以及顺序保持一致,否则无法匹配
除了单个字符,也可以设置要匹配字符的范围
范围匹配符号
范围匹配符号 | 描述 |
---|---|
[abc] | 可能是abc任意一个 |
[^abc] | 字母不是abc中任意一个 |
a-zA-Z | 表示全部由字母组成,包括大小写 |
0-9 | 表示由数字组成 |
案例一:字符匹配的范围控制
数量匹配符号
符号 | 描述 | 待匹配符号举例 | 正则表达式写法 |
---|---|---|---|
? | 前面的匹配字符出现0或1次 | P、PY | PY? |
* | 匹配字符出现0或1或多次 | P、PY、PYY、… | PY* |
+ | 匹配字符出现一次或多次 | PY、PYY、… | PY+ |
{n} | 匹配字符出现n次 | PYYY | PY{3} |
{n,} | 匹配字符出现n次以上 | PY、PYY、PYYY | PY{1,} |
{n,m} | 匹配字符出现n~m次 | PY、PYY | PY{m,n} |
案例二:字符匹配的数量控制
简化正则表达式
用于简化正则匹配符号定义,利用简化表达式可以对数字、字母、空格等内容进行匹配
简化正则表达式 | 匹配内容 | 其它正则符号表示 |
---|---|---|
\d | 一位数字 | 等价于[0-9] |
\D | 一位非数字 | 等价于[^0-9] |
. | 任意一个字符,无法匹配换行符 | |
\w | 一位字母,数字或下划线, | 等价于[a-zA-Z0-9_] |
\W | 一位非字母,非数字或下划线 | 等价于[^a-zA-Z0-9_] |
\s | 空白符(如换行符,tab) | |
\S | 非空白符 | 常与\s组合使用匹配所有的字符 |
正则表达式中的逻辑符
正则表达式中允许存在“与”“或”的逻辑关系
正则逻辑表达式 | 描述 |
---|---|
正则A正则B | 表达式A后紧跟表达式B |
正则A|正则B | 表达式A或表达式B |
案例三:多个示例正则表达式
- 匹配合法的ip地址:
^\d{1,3}\.\d{1.3}\.\d{1.3}\.\d{1,3}
- 匹配是否为移动号码:
^(13[1-9]\d{8})(15[01289]\d{8})$
- 匹配任意汉字(unicode编码):
[\u4e00-\u9fa5]
- 匹配合法的身份证号码:
^d{18}|\d{15}
- 匹配合法的电子邮箱地址:
^\w+@(\w+\.)+\w+$
正则匹配模式
正则表达式匹配时通过正则匹配模式进行匹配控制
下面介绍一些常用的正则匹配模式
模式 | 描述 |
---|---|
I | 忽略大小写 |
L | 字符集本地化表示 |
M | 多行匹配模式 |
S | 使元字符’.’可以匹配换行符在内的任意字符 |
X | 忽略正则表达式中的空白和注释 |
U | 匹配unicode字符 |
分组
- 一个正则表达式可以匹配任意多个数据内容,通过分组的形式对数据进行归类可以更加清晰地获得子数据
- 正则表达式中通过“()”定义分组。
- 如果没有使用分组,整个正则表达式默认为是一个隐含的全局分组(索引为0)
分组正则表达式
表达式 | 模式 | 描述 |
---|---|---|
(?P<name>...) |
分组命名模式 | 可通过索引编号或name名称获取内容 |
(?P=name) |
分组引用模式 | 可以在正则表达式中引用前面命名过的正则表达式 |
(?:...) |
分组不捕获模式 | 计算索引时跳过该分组 |
(...) |
默认分组捕获模式 | 可单独取出分组内容 |
正则分组函数
根据索引返回正则匹配内容
函数 | 描述 |
---|---|
group() | 一个参数,返回单个字符串;多个参数,返回一个元组,元组里每一项对应一个参数。没有参数,参数默认为0(返回所有匹配内容) |
groups() | 返回一个包含所有匹配内容的元组 |
groupdict() | 返回一个字典,包含所有经命名的匹配分组,键值是分组名 |
注意:group()函数通过索引来获取数据,但是如果分组过多可能会造成索引混乱的问题,因此建议在进行分组时就对分组进行命名,后续通过分组名称获取数据
案例四:利用分组匹配日期
实际运用
re模块一般使用步骤
- 使用compile()函数将正则表达式的字符串形式生成为一个pattern对象
- 通过pattern对象的一系列方法对文本进行匹配,返回一个match对象
- 使用match对象的属性或方法查找所需要的信息
re模块使用两种形式
- 使用格式:
pattern对象.re模块常用函数(待匹配的文本)
- 使用格式:
re模块常用函数(pattern对象,待匹配的文本)
案例一:豆瓣250部分网页源码
问题:从给定的一段代码中找到特定的信息
<ol class="grid_view">
<li>
<div class="item">
<div class="pic">
<em class="">1</em>
<a href="https://movie.douban.com/subject/1292052/">
<img width="100" alt="肖申克的救赎" src="https://img2.doubanio.com/view/photo/s_ratio_poster/public/p480747492.webp" class="">
</a>
</div>
<div class="info">
<div class="hd">
<a href="https://movie.douban.com/subject/1292052/" class="">
<span class="title">肖申克的救赎</span>
<span class="title"> / The Shawshank Redemption</span>
<span class="other"> / 月黑高飞(港) / 刺激1995(台)</span>
</a>
<span class="playable">[可播放]</span>
</div>
<div class="bd">
<p class="">
导演: 弗兰克·德拉邦特 Frank Darabont 主演: 蒂姆·罗宾斯 Tim Robbins /...<br>
1994 / 美国 / 犯罪 剧情
</p>
<div class="star">
<span class="rating5-t"></span>
<span class="rating_num"property="v:average">9.7</span>
<span property="v:best" content="10.0"></span>
<span>2424702人评价</span>
</div>
<p class="quote">
<span class="inq">希望让人自由。</span>
</p>
</div>
</div>
</div>
</li>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
正则表达式实现
# coding:utf-8
import re
text=open('肖申克的救赎.html','r')
content=text.read()
print(len(content))
mode=re.compile(r'<div class="pic">.*?<span class="title">(?P<name>.*?)</span>',re.S)
result=re.search(mode,content)
print(result.group('name'))
text.close()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
案例二:获取中国大学MOOC学校列表
问题:如何从给定的一个网页原文件(网页见:网页源码)中找到所有的学校名称1
正则表达式实现
import re
import requests
url='https://www.icourse163.org/university/view/all.htm#/'
resp=requests.get(url)
print(resp.status_code)
mode='alt="(?P<name>.*?)">'
list1=re.findall(mode,resp.text)
for name in list1:
print(name)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-
本案例参考《2021年9月计算机二级python考卷综合应用题》,有兴趣的小伙伴可以自己去找资源 ↩︎