1.正则表达式
re模块是python中提供和正则表达式相关操作的方法
1)什么是正则表达式
正则表达式是用来描述字符串规律的一种语法,可以更加方便的解决字符串匹配、字符串查找、字符串切割等相关操作
2)正则语法(通用的)
re.fullmatch(正则表达式,字符串) - 判断字符串和正则表达式是否完全匹配,如果不能匹配返回None
python是将正则表达式放在引号中
a.普通字符
如果正则表达式中出现普通字符,那么这个字符表示这个字符本身
# 一个字符串只有一个字符,并且这个字符是a
re_str = r'a'
result = re.fullmatch(re_str, 'a')
print(result)
b. . - 匹配任意字符
一个正则表达式中的点匹配一个任意字符
# 一个字符串有三个字符,第一个是a,最后一个是b,中间是任意字符
re_str = r'a.b'
result = re.fullmatch(re_str, 'a1b')
print(result)
c.\w(了解) - 匹配字母、数字、下划线
re_str = r'a\wb'
result = re.fullmatch(re_str, 'a_b')
print(result)
d.\s - 匹配空白字符
空白字符:空格、回车(\n)、制表符(\t)
re_str = r'abc\s123'
result = re.fullmatch(re_str, 'abc 123')
print(result)
# print(re_str)
# print(r'1\n1')
e.\d - 匹配一个数字字符
re_str = r'\d\d\d'
result = re.fullmatch(re_str, '111')
print(result)
f.\W \S \D
\S - 匹配一个非空白字符
\D - 匹配一个非数字字符
re_str = r'a.b\Sc\D'
result = re.fullmatch(re_str, 'asb1c_')
print(result)
g.[字符集] - 匹配字符集中任意一个字符
注意:一个[]只能匹配一个字符
a.[字符集] - 匹配字符集中任意一个字符,例如:[abc123]、[12abc3] ->匹配一个字符是a或者b或者1或者c或者2或者3
b.[字符1-字符2] - 匹配编码值在字符1编码到字符2编码中的所有字符中的任意一个(注意:字符1的编码值必须小于字符2)
数字字符:[0-9]
小写字母:[a-z]
大写字母:[A-Z]
字母:[a-zA-Z]
\w:[a-zA-Z0-9]
中文:[\u4e00-\u9fa5]
例如:[2-8abc]
[0-9abc] -> [\dabc]
re_str = r'a[hello_?]b'
print(re.fullmatch(re_str, 'a?b'))
re_str = r'[a-w]12'
print(re.fullmatch(re_str, 'q12'))
re_str = r'[\dabc]123'
print(re.fullmatch(re_str, '2123'))
h.[^字符集] - 匹配不在字符集中的任意一个字符
非数字字符:[^0-9]
非小写字母:[^a-z]
非字母:[^a-zA-Z]
非中文:[^\u4e00-\u9fa5]
print(re.fullmatch(r'[^123]ab', '4ab'))
3)检测字符的符号
a.\b - 检测是否是单词边界
单词边界 - 生活中凡是可以区分出两个不同单词的符号都是单词边界;空白字符、标点符号等
# 匹配一个字符串长度是6,字符分别是abc123,并且要求c和1之间是单词边界
re_str = r'abc\b123'
print(re.fullmatch(re_str, 'abc 123'))
re_str = r'abc \b123'
print(re.fullmatch(re_str, 'abc 123'))
re_str = r'\d\d[a-f]\b'
print(re.fullmatch(re_str, '78d'))
b.\B - 检测是否不是单词边界
print(re.search(r'\B\d\d\d\b', 'h789jkh890,kj'))
c.^ - 检测是否是字符串开头(必须是在[]外面)
re_str = r'^123'
print(re.fullmatch(re_str, '123'))
d.$ - 检测是否是字符串结尾(必须是在[]外面)
re_str = r'abc123$'
print(re.search(r'\d\d$', '哈哈哈67'))
2.正则表达式
1)控制匹配次数的符号
a.* - 匹配0次或多次
普通字符* - 普通字符出现0次或多次;r'a123' -> '123', 'aa123',...
\d - \d出现0次或多次;'\dabc' -> 'abc', '223abc',...
[字符集] - [字符集]出现0次或多次;r'[abc]*123' -> 'a123', 'aab123',...
print(re.fullmatch(r'\d*abc', '165abc'))
b.+ - 匹配1次或多次
print(re.fullmatch(r'a+123', 'aa123'))
c.? - 匹配0次或1次
print(re.fullmatch(r'[-+]?\d\d\d', '-123'))
d.{}
{N} - 匹配N次
{M,N} - 匹配M到N次(至少M次,最多N次)
{M,} - 至少M次
{,N} - 最多N次
print(re.fullmatch(r'a{3}', 'aaa'))
print(re.fullmatch(r'\d{3,5}abc', '2313abc'))
# 密码:6-12的数字和字母
print(re.fullmatch(r'[\da-zA-Z]{6,12}', 'asjq182hk1'))
print(re.fullmatch(r'a{,3}123', 'aa123'))
2)贪婪和非贪婪
当匹配次数不确定的时候,匹配分为贪婪和非贪婪;默认都是贪婪的
贪婪 - 在匹配成功的前提下,次数尽可能多的去匹配
非贪婪 - 在匹配成功的前提下,次数尽可能少的去匹配(*?,+?,??,{M,N}?,{M,}?,{,N}?)
print(re.search(r'abc*', 'abcccc'))
print(re.search(r'abc*?', 'abccc'))
print(re.search(r'abc\d*', '哈哈哈abc1728311'))
print(re.search(r'abc\d*?', '哈哈哈abc1728311'))
3) | - 分之
正则1|正则2 - 匹配一个字符串满足正则1或者正则2
# 写一个正则要求匹配到的字符串是3个数字或者3个字母
print(re.fullmatch(r'\d{3}|[a-zA-Z]{3}', '291'))
4)() - 分组
a.做整体操作
re_str1 = r'(\d{3}|[A-Z]{2})abc'
print(re.fullmatch(re_str1, 'KJabc'))
b.重复内容 - 正则中在数字前加\,用来重复前面第几个分组匹配到的内容(一个括号就是一个分组)
# '123abc123', '234abc234'
re_str2 = r'(\d{3})abc\1{2}'
print(re.fullmatch(re_str2, '000abc000000'))
5)转义符号
a.转义符号
指的是为了让正则中有特殊意义的符号的意义消失,而在符号前加\
re_str3 = r'\d{2}\.\d{2}'
print(re.fullmatch(re_str3, '12.34'))
print(re.fullmatch(re_str3, '12=34')) # None
b.除了^方法放在[]的最开头,-放在[]中两个字符之间,其他单独存在有特殊意义的符号在[]中都是普通字符
例如:+,*,?,|,.,()等
re_str3 = r'\d{2}[.]\d{2}'
print(re.fullmatch(re_str3, '23=19')) # None
print(re.fullmatch(re_str3, '23.19'))
3.re模块的使用
1)compile
compile(正则表达式) - 根据正则表达式创建正则对象
re_abj = re.compile(r'\d{2}')
re_abj.fullmatch('78')
re.fullmatch(r'\d{2}', '78')
2)匹配
fullmatch(正则表达式,字符串) - 完全匹配,让整个字符串和正则表达式进行匹配,如果匹配成功返回匹配对象,否则返回None
match(正则表达式,字符串) - 匹配字符串开头。如果匹配成功返回匹配对象,否则返回None
re_str = r'\d{3}'
result1 = re.fullmatch(re_str, '879')
print(result1)
result2 = re.match(re_str, '123哈哈哈78')
print(result2)
匹配对象
result2 = re.match(r'(\d{3})([a-z])abc', '123wabc哈哈哈78')
a.获取匹配结果(匹配到的子串)
匹配对象.group() - 获取整个正则表达式匹配到的结果
匹配对象.group(N) - 获取正则表达式中第N个分组匹配到的结果
print(result2.group()) # 123wabc
print(result2.group(1)) # 123
print(result2.group(2)) # w
b.获取匹配结果在原字符串中的范围 - 返回:(开始下标,结束下标),结束下标取不到
匹配对象.span() - 获取整个正则表达式匹配结果在原字符串中的范围
匹配对象.span(N) - 获取指定分组匹配结果在原字符串中的范围
print(result2.span(2)) # (3,4)
c.获取原字符串
print(result2.string) # 123wabc哈哈哈78
3)查找
a.搜索
search(正则表达式,字符串) - 获取字符串中第一个满足正则表达式的子串;如果有就返回匹配对象,没有返回None
print(re.search(r'\d{3}', 'hhh192hhh879jah'))
b.findall
findall(正则表达式,字符串) - 获取字符串中所有满足正则表达式的子串,返回值是列表,列表中的元素就是满足要求的子串
print(re.findall(r'\d{3}', 'hhh123aka718821jh122')) # ['123', '718', '821', '122']
# 注意:如果finall中的正则表达式中有一个分组;返回列表中的元素只取匹配结果中分组对应的部分
print(re.findall(r'(\d{3})[a-z]{2}', 'hhh123ak5a718821jh122')) # ['123', '821']
# 注意:如果正则表达式中有多个分组,返回的列表中的元素是元组,元组中的元素是每个分组对应的结果
print(re.findall(r'(\d{3})([a-z]{2})', 'hhh123ak5a718821jh122')) # [('123', 'ak'), ('821', 'jh')]
c.finditer
finditer(正则表达式,字符串) - 获取字符串中所有满足正则表达式的子串,返回值是迭代器,迭代器中的元素是匹配对象
result3 = re.finditer(r'(\d{3})([a-z]{2})', '213as===-891ja=181hj,,')
result3 = list(result3)
print(result3[0].group(1), result3[1].group(2))
4)切割
re.split(正则表达式,字符串) - 将字符串中所有和正则表达式匹配的子串作为切割点,对字符串进行切割;返回值是列表
str1 = '假1设农12安;回56复win,煎熬?jao ,a8h'
print(re.split(r'[,;!.?\s]', str1))
5)替换
re.sub(正则表达式,字符串1,字符串2) - 将字符串2中所有满足正则表达式的子串都替换成字符串1
print(re.sub(r'\d+', '+', str1)) # 假+设农+安;回+复win,煎熬?jao ,a+h
# re.IGNORECASE 和 re.I - 表示匹配的时候忽略大小写