python正则表达式:match()、search()、findall()、sub()、split()

正则表达式介绍

详见:正则表达式

python 的正则表达式

Python 的 re 模块,提供正则表达式功能

导入 re 模块

import re

相关api

  • re.match()
  • re.search()
  • findall()
  • re.split()
  • re.sub()

re.match()

从字符串的 起始位置 匹配正则表达式,如果不是起始位置匹配成功的话,就返回 None

由于从 起始位置 匹配正则表达式,会受到很多限制,使用较少

函数声明

re.match(pattern, string, flags=0)

参数:

  • pattern:正则表达式
  • string:要匹配的字符串
  • flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等,详见下面 标志位

返回值:

  • 匹配成功,返回 re.MatchObject 类型,详见下面
  • 没有匹配,返回 None

标志位

flags 具体参数为:

  • re.I:忽略大小写
  • re.L:表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
  • re.M:多行模式
  • re.S:即为 . 并且包括换行符在内的任意字符(. 不包括换行符)
  • re.U:表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
  • re.X:为了增加可读性,忽略 空格 和 # 后面的注释

re.match()返回值的函数

  • group(num=0): 返回匹配正则表达式的字符串,group()可以一次输入多个组号,在这种情况下将返回一个包含组所对应的值的元组
  • groups(): 返回包含所有子组字符串的元组
  • groupdict(): 返回有别名的组的别名为“键”、以该组截获的子字符串为“值”的字典
  • start(): 返回匹配字符串在原始字符串的开始位置
  • end(): 返回匹配字符串在原始字符串的结束位置
  • span(): 返回包含匹配的位置(开始、结束)的元组

例子-提取手机号

从开始位置匹配手机号,如果符合手机号格式(第一个数字是1,第二个数字是3或5或8,后面是9个数字),将该 手机号打印出来

该功能通过 if 语句,可以实现,但编写代码复杂,如果使用 正则表达式,几行代码即可搞定

import re

s = "13812345678是我的手机号"

# 从开头开始匹配,如果第一个数字是1,第二个数字是3或5或8,后面是9个数字,就认为匹配成功
res = re.match("1[358]\d{9}", s)

print(type(res)) # res 是 <class 're.Match'> 类型
print(res) # 查看 res 内容: <re.Match object; span=(0, 11), match='13812345678'>


print(res.group()) # 匹配的字符串,即:13812345678
print(res.start()) # 匹配开始位置,即:0
print(res.end()) # 匹配结束位置,即:11
print(res.span()) # 返回元组,第一个元素是开始位置,即:0,第二个元素是结束位置,即:11

例子-校验手机号

有些登录页面,需要输入 手机号、邮箱地址,可以用此方法校验手机号、邮箱地址是否正确

分析:输入的内容要 完全匹配 手机号格式。与 提取手机号 的例子不同,该例子是后面可以有其他字符串

正则表达式: 1[358]\d{9}$,最后要有 $,表示匹配到末尾

匹配成功例子:

s1 = "13812345678"
res = re.match("1[358]\d{9}$", s1)
print(res)

执行结果:

<re.Match object; span=(0, 11), match='13812345678'>

匹配失败例子:

# 12个数字,不符合格式,返回None
s2 = "138123456781"
res = re.match("1[358]\d{9}$", s2)
print(res)

执行结果:

None

例子-匹配不上

接上面例子,如果手机号不能匹配正则表达式,将返回 None

import re

s = "110是我的手机号"

# 从开头开始匹配,如果第一个数字是1,第二个数字是3或5或8,后面是9个数字,就认为匹配成功
res = re.match("1[358]\d{9}", s)

print(res) # None

缺点

格式正确的手机号,如果 不在开始位置,就不能匹配上,如下例子:

s = "我的手机号是:13812345678"
res = re.match("1[358]\d{9}", s)
print(res)

re.MatchObject 对象

调用 正则表达式相关函数后,如果有匹配的,就返回 re.MatchObject 对象

如: 调用 re.match() ,如果有匹配的,就返回 re.MatchObject 对象

常见方法

  • res.group():返回匹配的字符串
  • res.start():返回匹配开始位置
  • res.end():返回匹配结束位置
  • res.span():返回元组,第一个元素是开始位置,第二个元素是结束位置

例子

见 re.match() 中的例子

re.search()

在 整个字符串 中查找匹配正则表达式的部分,并返回第一个匹配的部分

应用场景

在字符串 我的手机号是:13812345678,韩梅梅的手机号是:13912345678,有2个手机号匹配正则表达式,而且 不在开始位置,但 只返回第一个手机号

与 re.match() 的区别

格式正确的手机号,即使 不在开始位置,re.search() 也能匹配上,但 re.match() 就不能匹配上

re.search() 没有 re.match() 限制,使用较多

函数声明

re.search(pattern, string, flags=0)

参数:

  • pattern:正则表达式
  • string:要匹配的字符串
  • flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等

返回值:

  • 匹配成功,返回 re.MatchObject 类型,详见下面
  • 没有匹配,返回 None

例子

在字符串 我的手机号是:13812345678,韩梅梅的手机号是:13912345678,有2个手机号匹配正则表达式,但只返回第一个手机号

s = "我的手机号是:13812345678,韩梅梅的手机号是:13912345678"
res = re.search("1[358]\d{9}", s)
print(type(res)) # <class 're.Match'>
print(res)
print(res.group())
print(res.span())
print(res.start())
print(res.end())

执行结果:

<class 're.Match'>
<re.Match object; span=(7, 18), match='13812345678'>
13812345678
(7, 18)
7
18

例子-校验手机号

有些登录页面,需要输入 手机号、邮箱地址,可以用此方法校验手机号、邮箱地址是否正确

分析: re.search() 没有 re.match() 的限制,输入的内容要 完全匹配 手机号格式

正则表达式: ^1[358]\d{9}$,^表示从头开始匹配,$表示匹配的末尾

匹配成功例子:

s1 = "13812345678"
res = re.search("^1[358]\d{9}$", s1)
print(res)

执行结果:

<re.Match object; span=(0, 11), match='13812345678'>

匹配失败例子:

s1 = "138123456781" # 手机号是12位,就匹配不上
res = re.search("^1[358]\d{9}$", s1)
print(res)

执行结果:

None

re.findall()

找到匹配正则表达式的所有内容,将这些内容放入列表中,并返回该列表,如果没有找到匹配的,则 返回空列表

函数声明

re.findall(pattern, string, flags=0)

参数:

  • pattern:正则表达式
  • string:要匹配的字符串
  • flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等

返回值:

  • 找到匹配的内容,将这些内容放入列表中,并返回该列表
  • 如果没有找到匹配的,则 返回空列表

例子

s = "我的手机号是:13812345678,韩梅梅的手机号是:13912345678"
res = re.findall("1[358]\d{9}",s)
print(type(res)) # <class 're.Match'>
print(res)

re.sub() 替换

将匹配的内容替换成指定的字符串

函数声明

re.sub(pattern, repl, string, count=0, flags=0)

参数:

  • pattern : 正则表达式
  • repl : 替换的内容
  • string : 要匹配的字符串
  • count : 替换的最大次数,默认 0 表示替换所有

返回值: 替换后的字符串

例子

将弹幕、评论中的 笨蛋、蠢蛋、二货 替换成 小可爱

s = "李雷是笨蛋,韩梅梅是蠢蛋,lucy是二货"
res = re.sub("笨蛋|蠢蛋|二货","小可爱",s)
print(res)

执行结果:

李雷是小可爱,韩梅梅是小可爱,lucy是小可爱

re.split()

根据指定的字符串拆分,返回数组。

但是,当遇到字符串 "1a2b3c4",根据字母拆分数组时,就需要用到 正则表达式

函数声明

re.split(pattern, string[, maxsplit=0, flags=0])

参数:

  • pattern : 正则表达式
  • string : 要匹配的字符串
  • maxsplit:分隔次数,默认为 0,不限制次数;maxsplit=1 分隔一次
  • flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等

返回值: 列表,字符串分割后的内容

例子

按照字母拆分

s = "1a2b3c4"
res = re.split("[a-z]", s)
print(res)

执行结果:

['1', '2', '3', '4']

复杂案例

按照字母、空格、制表符、, 进行拆分,最后提取的是数字

s = "Lilei is 20,Hanmeimei is 21,lucy is 22,lili is 22"
res = re.split("[a-zA-Z,\s]+",s)
print(res)

执行结果:

['', '20', '21', '22', '22']

注意:字符串开头、结尾有匹配的内容,那么返回list中,第一个元素、最后一个元素就会有空字符串 ''