总结
检测类的符号
\b - 检测是否是单词边界
"""
凡是可以将两个单词分开的符号,都是单词边界
比如:空白字符、标点符号对应的字符、字符串开头和结尾
"""
re_str = r'abc123\b'
print(fullmatch(re_str, 'abc123'))
re_str = r'\b\d\d\b'
result = findall(re_str, 'shj瓦达12,32 siif21,,24机房is就,打打21')
print(result) # ['32']
检测类的符号:是在匹配成功的情况下,看检测类符号所在的位置是否符合要求
\B - 检测是否不是单词边界
re_str = r'\B\d\d\B'
result = findall(re_str, 'shj瓦达1232 siif2124机房is就,打打21')
print(result) # ['12', '21', '24']
^ - 检测是否是字符串开头
re_str = '^\d\d'
result = findall(re_str, '22你打得我打打打安德森的提高')
print(result)
$ - 检测是否是字符串结尾
re_str = '\d\d$'
result = findall(re_str, '你打得我打1231打打安34德森的提高45')
print(result)
匹配次数
*- 0次或者多次(任意次数)
"""
*a - a出现0次或多次
\d* - \d出现0次或多次,每次的一个\d可以是任意一个数字
[abc]* - [abc]出现0次或多次,每次的[abc]都可以在a,b,c中任意选一个
"""
re_str = r'a\d*b'
print(fullmatch(re_str, 'ab'))
print(fullmatch(re_str, 'a1b'))
print(fullmatch(re_str, 'a3231b'))
±1次或者多次(至少一次)
re_str = r'a\d+b'
print(fullmatch(re_str, 'a1b'))
print(fullmatch(re_str, 'a12492b'))
? - 0次或1次
re_str = r'[+-]?[1-9]\d'
print(fullmatch(re_str, '-20'))
print(fullmatch(re_str, '+90'))
print(fullmatch(re_str, '39'))
{}
"""
{N} - 匹配N次
{M,N} - 匹配M到N次,MN都能取的到
{M,} - 匹配至少M次
{,N} - 匹配最多N次
"""
re_str = r'1a{2,5}2'
print(fullmatch(re_str, '1aaaaa2'))
贪婪和非贪婪
"""
在匹配次数不确定的时候才有贪婪和非贪婪
贪婪: 在能匹配成功的前提下,取匹配次数最多的次数(默认情况下)
非贪婪: 再能匹配成功的前提下去匹配次数最少的次数(在匹配次数后加?)
"""
re_str = r'a.+?b'
print(fullmatch(re_str, 'ahsjbhksb'))
print(match(re_str, 'adbuybs12bsdfdnbi'))
分组和分支
分组 - ()
# 用法1:将正则表达式中的一部分作为一个整体,进行整体相关操作,比如控制次数
# 'amn12ams34fsa67'
re_str = r'([a-z]{3}\d{2}){3}'
print(fullmatch(re_str, 'amn12ams34fsa67'))
# '22a34a56a34' - 整体
re_str = r'(\d{2}a){3}\d{2}'
print(fullmatch(re_str, '22a34a56a34'))
# 用法2:重复 - 使用\M 来重复前面第M个分组中的内容
re_str = r'(\d{2})abc\1'
print(fullmatch(re_str, '78abc78'))
re_str = r'(\d{2})=([\u4e00-\u9fa5])=\2=\1'
print(fullmatch(re_str, '23=你=你=23'))
re_str = r'(\d{2})=\1=([\u4e00-\u9fa5])=\1'
print(fullmatch(re_str, '34=34=你=34'))
分支 - |
"""
正则表达式1|正则表达式2 - 先让正则1和字符串进行匹配,如果匹配成功就成功,如果失败就和正则2进行匹配,
如果正则2成功结果过匹配成功,否则匹配失败,(两个正则中只有一个可以匹配成功)
"""
# '23abc' 、 'MKHabc'
re_str = r'\d{2}abc|[A-Z]abc'
print(fullmatch(re_str, '23abc'))
re_str = r'(\d{2}|[A-Z]{3})abc'
print(fullmatch(re_str, '12abc'))
转义符号
在本身具备特殊功能或者特殊意义的符号前加, 让其功能消失,表示一个普通符号
re_str = r'[1-9]\d\.\d{2}'
print(fullmatch(re_str, '90.01'))
# '2+9'
re_str = r'\d\+\d'
print(fullmatch(re_str, '1+2'))
注意:独立具备特殊功能的符号在[]中功能会自动消失,例如+、*、?、.、()、
本身在[]中有特殊意义的就要特别注意:^、-、[、]
re模块
compile(正则表达式) - 创建一个正则表达式对象
re_obj = compile(r'\d{3}')
result = re_obj.fullmatch('123')
print(result)
print(fullmatch(r'\d{3}', '123'))
匹配类方法
"""
1)fullmatch
fullmatch(正则表达式, 字符串)
正则表达式对象.fullmatch(字符串)
判断整个字符串是否符合正则表达式描述的规则,如果不符合返回None,符合返回匹配对象
2)match
match(正则表达式, 字符串)
正则表达式对象.match(字符串)
判断字符开头是否符合正则表达式描述规则,如果不符合返回None,符合返回匹配对象
"""
result = match(r'(\d{3})-([a-z]{2,5})', '872-dhn8dsdjjs23')
print(result) # <re.Match object; span=(0, 7), match='872-dhn'>
# 1)匹配对象 - 获取整个正则表达式匹配到的结果
# 匹配对象.group() / 匹配对象.group(0) - 获取整个正则表达式匹配到的结果
# 匹配对象.group(N) - 获取正则表达式中第N个分组匹配到的结果
print(result.group()) # 872-dhn
print(result.group(1)) # 872
print(result.group(2)) # dhn
# 2) 获取匹配结果在原字符中的位置
# 匹配对象.span()
# 匹配对象.span(N)
print(result.span()) # [0, 7)
print(result.span(2))
# 3) 获取原字符串
# 匹配对象.string
print(result.string) # 872-dhn8dsdjjs23
查找类方法方法
"""
search(正则表达式,字符串)
正则表达式对象.search(字符串) - 获取字符串中第一个满足正则表达式的子串,如果没有返回None,否则返回匹配对象
"""
result = search(r'\d{3}', 'ssda234454353534dfsfsd')
print(result) # <re.Match object; span=(4, 7), match='234'>
"""
findall(正则表达式, 字符串)
正则表达式对象.findall(字符串) - 获取字符串中满足正则表达式的子串,以列表形式返回,列表中的元素是字符串
"""
str1 = 'shj24睡的我34=-37ml899计算机上23.90m7788'
result = findall(r'\d+', str1)
print(result) # ['24', '34', '37', '899', '23', '90', '7788']
result = findall(r'[\u4e00-\u9fa5]\d+', str1)
print(result) # ['我34', '上23']
如果正则中有分组,findall只提取匹配结果中分组匹配到的内容
result = findall(r'[\u4e00-\u9fa5](\d+)', str1)
print(result) # ['34', '23']
"""
findiiter(正则表达式, 字符串)
正则表达式对象.finditer(字符串) - 获取字符串中所有满足正则表达式的子串,返回值是迭代器,迭代器中的元素是匹配对象
"""
str1 = 'shj24萨克斯38904=-37ml899计算机上3,90m7788'
result = finditer(r'\d+', str1)
print(list(result))
result = finditer(r'(\d+)-([a-z]+)', 'hshs899-mn生死狙击2-mkl==-892-ma=计算机')
print('整个正则匹配结果:', [x.group() for x in result]) # 整个正则匹配结果: ['899-mn', '2-mkl', '892-ma']
result = finditer(r'(\d+)-([a-z]+)', 'hshs899-mn生死狙击2-mkl==-892-ma=计算机')
print('分组1的匹配结果:', [x.group(1) for x in result]) # 分组1的匹配结果: ['899', '2', '892']
切割 - 灵活
"""
split(正则表达式, 字符串)
正则表达式对象.split(字符串) - 将字符串中所有满足正则表达式的子串作为切割点对字符串进行切割
split(正则表达式, 字符串, 最大切割数)
"""
str1 = '节省时间27计算机上9sjjsn6计算机0292jsjsn就几节课2-==解决'
result = split(r'\d+', str1)
print(result) # ['节省时间', '计算机上', 'sjjsn', '计算机', 'jsjsn就几节课', '-==解决']
str2 = '失敬失敬,啥的看法和。适得府君书就,随叫随到加分号。是计算机上'
result = split(r'[,。]', str2)
print(result) # ['失敬失敬', '啥的看法和', '适得府君书就', '随叫随到加分号', '是计算机上']
result = split(r'[,。]', str2, 3)
print(result) # ['失敬失敬', '啥的看法和', '适得府君书就', '随叫随到加分号。是计算机上']
替换
"""
sub(正则表达式, 字符串1, 字符串2)
正则表达式对象.sub(字符串1, 字符串2) - 将字符串2中所有满足正则表达式的子串都替换成字符串1
"""
result = sub(r'\d+', '+', '试试7数据09jsjs8989sj计算机上-=')
print(result) # 试试+数据+jsjs+sj计算机上-=
result = sub(r'\d', '+', '试试7数据09jsjs8989sj计算机上-=')
print(result) # 试试+数据++jsjs++++sj计算机上-=
result = sub(r'傻[bB逼]|f\s*u\s*c\s*k', '*', 'f u c k!')
print(result)
result = sub(r'\d', '+', '试试7数据09jsjs8989sj计算机上-=', 3)
print(result) # 试试+数据++jsjs8989sj计算机上-=
匹配参数
单行匹配和多行匹配
"""
默认是多行匹配。
多行匹配的时候. 不能和\n(换行)匹配;
单行匹配的时候. 可以和\n(换行)匹配
"""
# 多行
print(fullmatch(r'a.b', 'a\nb')) # None
# 单行
print(fullmatch(r'a.b', 'a\nb', flags=S)) # S是从re模块里导进来的
print(fullmatch(r'(?s)a.b', 'a\nb')) # <re.Match object; span=(0, 3), match='a\nb'>
忽略大小写
"""
默认不忽略大小写。
忽略大小写的时候,大写字母可以和对应的小写字母匹配,小写字母也可以和对应的大写字母匹配
"""
# 忽略大小写
print(fullmatch(r'[a-z]{3}123', 'hSm123', flags=I)) # <re.Match object; span=(0, 6), match='hSm123'>
print(fullmatch(r'(?i)[a-z]{3}123', 'hSm123'))
单行匹配和忽略大小写同时进行
print(fullmatch(r'abc.123', 'ABC\n123', flags=I | S))
print(fullmatch(r'(?si)abc.123', 'ABC\n123')) # <re.Match object; span=(0, 7), match='ABC\n123'>
作业
# 用户名匹配
re_str = r'\D\w{5,15}'
print(fullmatch(re_str, 'a12311'))
# 密码匹配
re_str = r'[a-z|A-Z]\w{5,15}'
print(fullmatch(re_str, 'a111111111111111'))
# ipv4 格式的 ip 地址匹配
# 提示: IP地址的范围是 0.0.0.0 - 255.255.255.255
re_str = r'^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[09][0-9]|[1-9][0-9]|[0-9])$'
print(fullmatch(re_str, '0.0.0.0'))
# 提取用户输入数据中的数值 (数值包括正负数 还包括整数和小数在内) 并求和
# 例如:“-3.14good87nice19bye” =====> -3.14 + 87 + 19 = 102.86
result = r'[-+]?\d+\.?\d*'
result_value = findall(result, '-3.14good87nice19bye')
sum1 = 0
for x in result_value:
print(x, type(x))
sum1 += eval(x)
print(sum1)
# 验证输入内容只能是汉字
re_chinese = r'[\u4e00-\u9fa5]+'
print(fullmatch(re_chinese, '我爱你'))
# 匹配整数或者小数(包括正数和负数)
re_num = r'[+-]?\d+\.?\d+'
print(fullmatch(re_num, '+903'))
# 验证输入用户名和QQ号是否有效并给出对应的提示信息
# 拆分长字符串:将一首诗的中的每一句话分别取出来
poem = '窗前明月光,疑是地上霜。举头望明月,低头思故乡。'
result = split(r'[,。]', poem, 4)
result.remove('')
print(result)