python 正则模块(re)

本文介绍了Python的re模块,详细讲解了正则表达式的应用场景,如手机号、邮箱的校验,以及re模块的常用函数,如match、search、findall、split、sub和subn的用法,并给出了多个实际案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.正则表达式常见的具体应用场景如下:

  1. 手机号校验;

  2. 邮箱校验;

  3. 身份证校验;

  4. 网页标签匹配;

  5. 车牌号校验;

  6. 中文校验;

2.re模块

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。re 模块使 Python 语言拥有全部的正则表达式功能。 

1>元字符,量词,贪婪与非贪婪匹配,分组与或的使用

元字符:

字符功能
.匹配任意1个字符(除了\n)
[ ]匹配[ ]中列举的字符
\d匹配数字,即0-9
\D匹配非数字,即不是数字
\s匹配空白,即 空格
\S匹配非空白
\w匹配单词字符,即a-z、A-Z、0-9、_
\W匹配非单词字符
#案例演示01:(.	匹配任意1个字符(除了\n))


# .	匹配任意1个字符(除了\n)
import re

ret = re.match("t.o", "t\no")
if ret:
    print(ret.group())
else:
    print("匹配失败")

# .	匹配任意1个字符(除了\n)
import re

ret = re.match("t.o", "two")
if ret:
    print(ret.group())
else:
    print("匹配失败")


#案例演示02:([ ]   匹配[ ]中列举的字符 ,只匹配任意一个字符)


# [ ]	匹配[ ]中列举的字符 ,只匹配任意一个字符
import re

ret = re.match("t[1wqs]o", "two")   # 将w换成9,查看匹配结果
if ret:
    print(ret.group())
else:
    print("匹配失败")


#案例演示03:(\d  匹配数字,即0-9)


# \d	匹配数字,即0-9
import re

ret = re.match("t\do", "t6o")   # 将6换成a,查看匹配结果
if ret:
    print(ret.group())
else:
    print("匹配失败")


#案例演示04:(\D  匹配非数字,即不是数字)


# \D	匹配非数字,即不是数字
import re

ret = re.match("t\Do", "two")   # 将w换成7,查看匹配结果
if ret:
    print(ret.group())
else:
    print("匹配失败")


#案例演示05:(\s  匹配空白,即 空格)


# \s	匹配空白,即 空格
import re

ret = re.match("t\so", "t o")   # 将空格换成z,查看匹配结果
if ret:
    print(ret.group())
else:
    print("匹配失败")


#案例演示06:(\S  匹配非空白)


# \S	匹配非空白
import re

ret = re.match("t\So", "two")  # 将w替换成空格,查看匹配结果
if ret:
    print(ret.group())
else:
    print("匹配失败")


#案例演示07:(\w  匹配单词字符,即a-z、A-Z、0-9、_)


# \w	匹配单词字符,即a-z、A-Z、0-9、_
import re

ret = re.match("t\wo", "t_o")   # 将_分别替换成a、A、z、Z,分别查看匹配结果
if ret:
    print(ret.group())
else:
    print("匹配失败")


#案例演示08:(\W  匹配非单词字符)


# \W	匹配非单词字符
import re

ret = re.match("t\Wo", "t%o")   # 将%分别替换成a、A、#、&,分别查看匹配结果
if ret:
    print(ret.group())
else:
    print("匹配失败")

量词:

字符功能
*匹配前一个字符出现0次或者无限次,即可有可无
+匹配前一个字符出现1次或者无限次,即至少有1次
?匹配前一个字符出现1次或者0次,即要么有1次,要么没有
{m}匹配前一个字符出现m次
{m,n}匹配前一个字符出现从m到n次
案例演示01:(*   匹配前一个字符出现0次或者无限次,即可有可无)


# *	匹配前一个字符出现0次或者无限次,即可有可无
import re
ret = re.match("tw*o","twwo")   # 将ww分别替换成w、www、wwwwwwwww或者删除ww,分别查看匹配结果
if ret:
    print(ret.group())
else:
    print("匹配失败")


案例演示02:(+   匹配前一个字符出现1次或者无限次,即至少有1次)


# +	匹配前一个字符出现1次或者无限次,即至少有1次
import re
ret = re.match("tw+o","twwo")    # 将ww分别替换成w、www、wwwwwwwww或者删除ww,分别查看匹配结果,并比较与									*的区别
if ret:
    print(ret.group())
else:
    print("匹配失败")


案例演示03:(?   匹配前一个字符出现1次或者0次,即要么有1次,要么没有)


# ?	匹配前一个字符出现1次或者0次,即要么有1次,要么没有        
import re
ret = re.match("tw?o","to")
if ret:
    print(ret.group())
else:
    print("匹配失败")

贪婪与非贪婪匹配:(?非贪婪匹配 +* 贪婪匹配)

案例演示04:({m} 匹配前一个字符出现m次)


# {m}	匹配前一个字符出现m次
import re
ret = re.match("tw{2}o", "twwo")   # 将ww替换为www,查看匹配结果,比较区别
if ret:
    print(ret.group())
else:
    print("匹配失败")


案例演示05:({m,n}   匹配前一个字符出现从m到n次)


# {m,n} 匹配前一个字符出现从m到n次
import re
ret = re.match("tw{3,5}o","twwwwwo")  # 将wwwww替换为ww,查看匹配结果
if ret:
    print(ret.group())
else:
    print("匹配失败")
    
# 特殊情况说明{3,},对应含义为:匹配前一字符至少出现三次的情况;
import re
ret = re.match("tw{3,}o","twwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwo")
if ret:
    print(ret.group())
else:
    print("匹配失败")
    
# 特殊情况说明{,5},对应含义为:匹配前一字符最多出现5次的情况;
import re
ret = re.match("tw{,5}o","twwwo")
if ret:
    print(ret.group())
else:
    print("匹配失败")

分组与或的使用:

匹配分组

字符功能
|匹配左右任意一个表达式
(ab)将括号中字符作为一个分组
\num引用分组num匹配到的字符串
(?P<name>)分组起别名
(?P=name)引用别名为name分组匹配到的字符串
案例演示01:((ab)    将括号中字符作为一个分组)

# (ab)	将括号中字符作为一个分组    www.baidu.com
import re
ret = re.match("^(https://www)\.[a-z]+(\.com)$", "https://www.baidu.com")
if ret:
    print(ret.group())
else:
    print("匹配失败")


案例演示02:(|   匹配左右任意一个表达式)


# 定义邮箱列表
email_list = ["xiaoWang@163.com", "xiaoWang@163.comheihei", "12345678@qq.com"]
# 导包
import re
# 遍历列表,获取列表中的邮箱字符串
for email in email_list:
    # 匹配每一个邮箱字符串,判断是否符合邮箱格式要求
    ret = re.match("\w{4,20}@(163|qq|sina|139)(.com)$", email)
    if ret:
        print("正确邮箱:", ret.group())
    else:
        print("%s匹配失败" % email)


案例演示03:(\num    引用分组num匹配到的字符串)


# 匹配标签:<html>hh</html>
# \num	引用分组num匹配到的字符串     r  声明原生字符,特别针对\等
import re
ret = re.match(r"<([a-z]+)>[a-z]{2}</\1>","<html>hh</html>")
if ret:
    print(ret.group())
else:
    print("匹配失败")


案例演示04:((?P<name>)  分组起别名, (?P=name)  引用别名为name分组匹配到的字符串 )


# 匹配标签:<html><h1>hh</h1></html>
# (?P<name>)	分组起别名
# (?P=name)	引用别名为name分组匹配到的字符串
import re
ret = re.match(r"<(?P<xiaohei>[a-z]{4})><(?P<xiaobai>\w{2})>[a-z]{2}</(?P=xiaobai)></(?P=xiaohei)>","<html><h1>hh</h1></html>")
if ret:
    print(ret.group())
else:
    print("匹配失败")

匹配开头

字符功能
^匹配字符串开头

现有王老师手机号:13051115888,要求使用正则表达式,判断该手机号是否合规?

思路分析:

  1. 手机号长度11位数字;

  2. 手机号以1开头;

  3. 手机号号段(3-8),例如:130、152、186,其中第二位为号段;

import re
ret = re.match("^1[3-8]\d{9}","13051115888")
if ret:
    print(ret.group())
else:
    print("匹配失败")

匹配结尾

字符功能
$匹配字符串以xxx结尾

现有赵老师邮箱号:zhaolaoshi123456@sina.com,要求使用正则表达式,判断该邮箱账号是否合规?

思路分析:

  1. 邮箱账号4-20位字符;

  2. 邮箱账号一般以.com结尾;

import re
ret = re.match("\w{4,20}@sina(.com)$","zhaolaoshi123456@sina.com")  # 正则表达式中的(),代表分组匹配
if ret:
    print(ret.group())
else:
    print("匹配失败")

2>re.match函数(re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。 )

用法:re.match(pattern, string, flags=0)

函数参数说明:

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

匹配成功re.match方法返回一个匹配的对象,否则返回None。

我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。

匹配对象方法描述
group(num=0)匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
groups()返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。

案例

# 导包
import re
# 使用re模块中的match(正则表达式,要匹配的字符串对象)方法进行匹配
ret = re.match("abc","abcdef")
if ret:  # 判断匹配结果是否存在
    print(ret.group())
else:
    print("匹配失败")

3>re.search函数(re.search 扫描整个字符串并返回第一个成功的匹配。 )

用法:re.search(pattern, string, flags=0)

函数参数说明:

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

匹配成功re.search方法返回一个匹配的对象,否则返回None。

我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。

匹配对象方法描述
group(num=0)匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
groups()返回一个包含所有小组字符串的元组,从 1 到 所含的小组号

 案例1

import re

ret_01 = re.search('www', 'www.runoob.com')  # 在起始位置匹配
if ret_01:
    print(ret_01.group())   # 查看匹配到的对象
    print(ret_01.span())    # 查看匹配到的对象的位置区间(下标索引)
else:
    print("ret_01 匹配失败")

 案例2

import re

ret_02 = re.search('com', 'www.runoob.com')  # 不在起始位置匹配
if ret_02:
    print(ret_02.group())  # 查看匹配到的对象
    print(ret_02.span())  # 查看匹配到的对象的位置区间(下标索引)
else:
    print("ret_02 匹配失败")

 案例3

import re
# 字符串
line = "Cats are smarter than dogs";
# search匹配(分组)
searchObj = re.search( r'(.*) are (.*?) .*', line, re.M|re.I)
# 如果匹配结果存在,则分组查看匹配数据
if searchObj:
   print "searchObj.group() : ", searchObj.group()
   print "searchObj.group(1) : ", searchObj.group(1)
   print "searchObj.group(2) : ", searchObj.group(2)
else:
   print "Nothing found!!"

4>re.findall函数(在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。 )

注意: match 和 search 是匹配一次 findall 匹配所有。

用法:findall(string[, pos[, endpos]])

参数:

  • string : 待匹配的字符串。

  • pos : 可选参数,指定字符串的起始位置,默认为 0。

  • endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。

查找字符串中的所有数字,返回包含所有匹配结果的列表:

案例

import re

pattern = re.compile(r'\d+')  # 查找数字
result1 = pattern.findall('runoob 123 google 456')
result2 = pattern.findall('run88oob123google456', 0, 10)

print(result1)
print(result2)

结果:
['123', '456']
['88', '12']

5>re.split函数(根据匹配进⾏切割字符串,并返回⼀个列表。)

用法:re.split(pattern, string, maxsplit=0, flags=0)

参数描述
pattern匹配的正则表达式
string要匹配的字符串
maxsplit分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数

案例:

import re
ret = re.split(r":| ","dasdsa:asdadas:dasdadada")
print(ret)

6>re.sub函数(sub是substitute的所写,表示替换,将匹配到的数据进⾏替换。)

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

#参数	描述
#pattern	必选,表示正则中的模式字符串
#repl	必选,就是replacement,要替换的字符串,也可为一个函数
#string	必选,被替换的那个string字符串
#count	可选参数,count 是要替换的最大次数,必须是非负整数。如果省略这个参数或设为 0,所有的匹配都会被替换
#flag	可选参数,标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等


import re
ret = re.sub(r"\d+", '998', "python = 997")
print(ret)

结果:
python=998

7>re.subn函数(行为与sub()相同,但是返回一个元组 (字符串, 替换次数)

用法:re.subn(pattern, repl, string[, count])返回:(sub(repl, string[, count]), 替换次数)


import re
pattern = re.compile(r'(\w+) (\w+)')
s = 'i say, hello world!'
print(re.subn(pattern, r'\2 \1', s))
def func(m):
    return m.group(1).title() + ' ' + m.group(2).title()
print(re.subn(pattern, func, s))

8>re.compile函数(compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。)

prog = re.compile(pattern)
result = prog.match(string)

等价于

result = re.match(pattern, string)

案例

>>>import re
>>> pattern = re.compile(r'\d+')   
m = pattern.match('one12twothree34four', 3, 10) # 从'1'的位置开始匹配,正好匹配
>>> print m                                         # 返回一个 Match 对象
<_sre.SRE_Match object at 0x10a42aac0>
>>> m.group(0)   # 可省略 0
'12'
>>> m.start(0)   # 可省略 0
3
>>> m.end(0)     # 可省略 0
5
>>> m.span(0)    # 可省略 0
(3, 5)

在上面,当匹配成功时返回一个 Match 对象,其中:

group([group1, …]) 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group() 或 group(0);
start([group]) 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;
end([group]) 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0;
span([group]) 方法返回 (start(group), end(group))


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值