2022年 11月 7日

python标准模块–re模块

目录

  • 正则简介
    • 正则表达函数
      • match函数
      • search函数
    • 正则匹配符号
      • 元字符
      • 字符匹配符号
      • 范围匹配符号
        • 案例一:字符匹配的范围控制
      • 数量匹配符号
        • 案例二:字符匹配的数量控制
      • 简化正则表达式
      • 正则表达式中的逻辑符
        • 案例三:多个示例正则表达式
    • 正则匹配模式
    • 分组
      • 分组正则表达式
      • 正则分组函数
        • 案例四:利用分组匹配日期
  • 实际运用
    • re模块一般使用步骤
    • re模块使用两种形式
        • 案例一:豆瓣250部分网页源码
        • 案例二:获取中国大学MOOC学校列表

正则简介

可能用到的网站

  1. 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

案例三:多个示例正则表达式

  1. 匹配合法的ip地址:^\d{1,3}\.\d{1.3}\.\d{1.3}\.\d{1,3}
  2. 匹配是否为移动号码:^(13[1-9]\d{8})(15[01289]\d{8})$
  3. 匹配任意汉字(unicode编码):[\u4e00-\u9fa5]
  4. 匹配合法的身份证号码:^d{18}|\d{15}
  5. 匹配合法的电子邮箱地址:^\w+@(\w+\.)+\w+$

正则匹配模式

正则表达式匹配时通过正则匹配模式进行匹配控制
下面介绍一些常用的正则匹配模式

模式 描述
I 忽略大小写
L 字符集本地化表示
M 多行匹配模式
S 使元字符’.’可以匹配换行符在内的任意字符
X 忽略正则表达式中的空白和注释
U 匹配unicode字符

分组

  1. 一个正则表达式可以匹配任意多个数据内容,通过分组的形式对数据进行归类可以更加清晰地获得子数据
  2. 正则表达式中通过“()”定义分组。
  3. 如果没有使用分组,整个正则表达式默认为是一个隐含的全局分组(索引为0)

分组正则表达式

表达式 模式 描述
(?P<name>...) 分组命名模式 可通过索引编号或name名称获取内容
(?P=name) 分组引用模式 可以在正则表达式中引用前面命名过的正则表达式
(?:...) 分组不捕获模式 计算索引时跳过该分组
(...) 默认分组捕获模式 可单独取出分组内容

正则分组函数

根据索引返回正则匹配内容

函数 描述
group() 一个参数,返回单个字符串;多个参数,返回一个元组,元组里每一项对应一个参数。没有参数,参数默认为0(返回所有匹配内容)
groups() 返回一个包含所有匹配内容的元组
groupdict() 返回一个字典,包含所有经命名的匹配分组,键值是分组名

注意:group()函数通过索引来获取数据,但是如果分组过多可能会造成索引混乱的问题,因此建议在进行分组时就对分组进行命名,后续通过分组名称获取数据

案例四:利用分组匹配日期

在这里插入图片描述

实际运用

re模块一般使用步骤

  1. 使用compile()函数将正则表达式的字符串形式生成为一个pattern对象
  2. 通过pattern对象的一系列方法对文本进行匹配,返回一个match对象
  3. 使用match对象的属性或方法查找所需要的信息

re模块使用两种形式

  1. 使用格式:pattern对象.re模块常用函数(待匹配的文本)
    在这里插入图片描述
  2. 使用格式: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">&nbsp;/&nbsp;The Shawshank Redemption</span>
                                <span class="other">&nbsp;/&nbsp;月黑高飞(港)  /  刺激1995(台)</span>
                        </a>


                            <span class="playable">[可播放]</span>
                    </div>
                    <div class="bd">
                        <p class="">
                            导演: 弗兰克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·罗宾斯 Tim Robbins /...<br>
                            1994&nbsp;/&nbsp;美国&nbsp;/&nbsp;犯罪 剧情
                        </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

  1. 本案例参考《2021年9月计算机二级python考卷综合应用题》,有兴趣的小伙伴可以自己去找资源 ↩︎