正则表达式

认识正则

正则表达式是一种可以让复杂的字符串问题变得简单的工具。

正则并不是Python特有语法(不属于python),所有的高级编程语言都支持正则,正则的语法通用。

不管通过正则表达式解决的是什么问题,写正则的时候都是在所有正则表达式描述字符串规则。

匹配类符号

Python的re模块

re模块是Python用来支持正则表达式的一个模块,模块中包含了所有和正则相关的函数。

fullmatch(正则表达式,字符串) - 判断正则表达式和指定的字符串是否完全匹配(判断整个字符串是否符合正则表 达式所描述的规则)
如果匹配成功返回匹配对象,匹配失败返回None

from re import fullmatch
正则语法 - 匹配类符号
  1. 普通符号 - 在正则表达式中表示符号本身的符号

    result1 = fullmatch(r'abc','abc')
    print(result1)    # <re.Match object; span=(0, 3), match='abc'>result2 = fullmatch(r'abc','acc')
    print(result2)    # None
    
  2. . - 匹配任意一个字符

    result = fullmatch(r'a.c','a+c')
    print(result)    # <re.Match object; span=(0, 3), match='a+c'>result = fullmatch(r'..abc','9%abc')
    print(result)   # <re.Match object; span=(0, 5), match='9%abc'>
    
  3. \d - 匹配任意一个数字字符

    result = fullmatch(r'a\dc','a5c')
    print(result)
    
  4. \s - 匹配任意一个空白字符

    空白字符:能产生空白效果的字符,例如:空格、换行、水平制表符

    result = fullmatch(r'a\sc','a\tc')
    print(result)result = fullmatch(r'\d\d\s.ab','34 吗ab')
    print(result)
    
  5. \D - 匹配任意一个非数字字符

    result1 = fullmatch(r'a\Dc','axc')
    print(result1)   # <re.Match object; span=(0, 3), match='axc'>result2 = fullmatch(r'a\Dc','a2c')
    print(result2)   # None
    
  6. \S - 匹配任意一个非空白字符

    result1 = fullmatch(r'a\Sc','a c')
    print(result1)     # Noneresult2 = fullmatch(r'a\Sc','a2c')
    print(result2)     # <re.Match object; span=(0, 3), match='a2c'>
    
  7. [字符集] - 匹配字符集中的任意一个字符

    (1) [abc] - 匹配a或者b或者c

    result = fullmatch(r'a[MN]b','aMb')
    print(result)  # <re.Match object; span=(0, 3), match='aMb'>
    result = fullmatch(r'a[MN]b','aNb')
    print(result)  # <re.Match object; span=(0, 3), match='aNb'>
    result = fullmatch(r'a[MN]b','amb')
    print(result)  # None
    

    (2) [abc\d] - 匹配a或者b或者c或者任意数字

    result = fullmatch(r'a[MN\d]b','a4b')
    print(result)    # <re.Match object; span=(0, 3), match='a4b'>
    

    (3) [1-9] - 匹配1-9中的任意一个数字

    result = fullmatch(r'a[1-9]c','a5c')
    print(result)    # <re.Match object; span=(0, 3), match='a5c'>
    result = fullmatch(r'a[1-9]c','a0c')
    print(result)    # None
    

    (4) [a-z] - 匹配任意一个小写字母

    result = fullmatch(r'a[a-z]c','adc')
    print(result)    # <re.Match object; span=(0, 3), match='adc'>
    result = fullmatch(r'a[a-z]c','aDc')
    print(result)    # None
    

    (5) [A-Z] - 匹配任意一个大写字母

    result = fullmatch(r'a[A-Z]c','aDc')
    print(result)    # <re.Match object; span=(0, 3), match='aDc'>
    result = fullmatch(r'a[A-Z]c','adc')
    print(result)    # None
    

    (6) [a-zA-Z] - 匹配任意一个字母

    result = fullmatch(r'a[a-zA-Z]c','aDc')
    print(result)    # <re.Match object; span=(0, 3), match='aDc'>
    result = fullmatch(r'a[a-zA-Z]c','adc')
    print(result)    # <re.Match object; span=(0, 3), match='adc'>
    

    (7)[a-zA-Z\d_] - 匹配字母数字或者下划线

    result = fullmatch(r'a[a-zA-Z\d_]c','a3c')
    print(result)    # <re.Match object; span=(0, 3), match='a3c'>
    result = fullmatch(r'a [a-zA-Z]c','a_c')
    print(result)    # <re.Match object; span=(0, 3), match='a_c'>
    

    (8) [\u4e00-\u9fa5] - 匹配任意一个中文字符

    result = fullmatch(r'a[\u4e00-\u9fa5]c','a火c')
    print(result)    # <re.Match object; span=(0, 3), match='a火c'>
    

    注意:[]中减号放在两个字符之间表示谁到谁(确定的方式是根据字符编码值大小绝对的);如果减号不在两个字符之间,就表示一个普通的减号。

  8. [^字符集] - 匹配不在字符集中的任意一个字符

    result = fullmatch(r'a[^MN]b','aMb')
    print(result)  # None
    result = fullmatch(r'a[^MN]b','a是b')
    print(result)  # <re.Match object; span=(0, 3), match='a是b'>
    

匹配次数

  1. * - 0次或多次(任意次数)

    注意:*在谁的后面控制的就是谁的次数
    a* - 0个或多个a
    \d* - 0个或多个\d

    result = fullmatch(r'a*123','aaa123')
    print(result)    # <re.Match object; span=(0, 6), match='aaa123'>result = fullmatch(r'\d*abc','110abc')
    print(result)   # <re.Match object; span=(0, 6), match='110abc'>
    
  2. + - 1次或者多次(至少一次)

    result = fullmatch(r'a+123','aaa123')
    print(result)    # <re.Match object; span=(0, 6), match='aaa123'>
    result = fullmatch(r'a+123','123')
    print(result)    # None
    
  3. ? - 0次或1次

    result = fullmatch(r'A?123','A123')
    print(result)
    
  4. {}

    {M,N} - M-N次
    {M,} - 至少M次
    {,N} - 至多N次
    {N} - N次

    result = fullmatch(r'[a-z]{3,5}123', 'bambk123')
    print(result)
    

练习1:写一个正则,判断输入的内容是否是一个合法的QQ号(长度是5~12位的数字,第一位不能是0)

qq = '2758716987'
result = fullmatch(r'[1-9]\d{4,11}',qq)
if result:print(f'{qq}合法')
else:print(f'{qq}不合法')

练习2:判断输入的内容是否是一个合法的标识符(由字母、数字下划线组成,数字不能开头)

str1 = 'abc'
result = fullmatch(f'[a-zA-Z_][a-zA-Z\d_]*',str1)
if result:print(f'{str1}合法')
else:print(f'{str1}不合法')

贪婪和非贪婪

match(正则表达式,字符串) - 判断字符串开头是否符合正则表达式描述的规则

from re import matchresult = match(r'\d{3}','234一二三yq')
print(result)   # <re.Match object; span=(0, 3), match='234'>

当匹配次数不确定的时候(*、+、?、{M,N}、{M,}、{,N})匹配模式分为贪婪和非贪婪两种,默认是贪婪的。

贪婪和非贪婪:在匹配成功的时候有多种匹配结果,贪婪取最多次数对应的匹配结果,非贪婪取最少次数对应的匹 配结果
(匹配次数不确定的地方,有多种匹配方式都可以匹配成功,贪婪取最多次数,非贪婪取最少次数)

贪婪模式:、+、?、{M,N}、{M,}、{,N}
非贪婪模式:
?、+?、??、{M,N}?、{M,}?、{,N}?

实例:

# 三种匹配结果:amb、amb计算b、amb计算bxxb
# 贪婪模式
result = match(r'a.+b','amb计算bxxbmn')
print(result)    # <re.Match object; span=(0, 9), match='amb计算bxxb'># 非贪婪模式
result = match(r'a.+?b','amb计算bxxbmn')
print(result)    # <re.Match object; span=(0, 3), match='amb'>

注意:如果匹配结果只有一种可能,那么贪婪和非贪婪的结果都一样

result = match(r'a.+b','ambxx')
print(result)   # <re.Match object; span=(0, 3), match='amb'>result = match(r'a.+?b','ambxx')
print(result)   # <re.Match object; span=(0, 3), match='amb'>

分组和分支

分组 ()
  1. 整体 - 将正则表达式中的一部分作为一个整体进行相关操作

    # '28GJ38VN37BK28QX...'
    result = fullmatch(r'(\d\d[A-Z]{2})+','80HK84VK13CN')
    print(result)    # <re.Match object; span=(0, 12), match='80HK84VK13CN'>
    
  2. 重复 - 可以在正则表达式中通过\M 来重复它前面的第M个分组的匹配结果

    # 23m23、98k98、12p12  -  能匹配
    # 23m34、98k08  -  不能匹配
    result = fullmatch(r'(\d{2})[a-z]\1','23m23')
    print(result)   # <re.Match object; span=(0, 5), match='23m23'># 23mkj=mkj23
    result = fullmatch(r'(\d{2})([a-z]{3})=\2\1{3}','23mkj=mkj232323')
    print(result)
    

    \M 只能重复在它出现之前的分组内容,无法重复在它之后出现的内容

    result = fullmatch(r'\d{2}\1\2=[a-z]{2}','2323mk=mk')     # 报错!
    print(result)
    
  3. 捕获 - 只获取正则表达式中的分组匹配到的结果(分为手动捕获和自动捕获两种)

    # findall(正则表达式,字符串)  -  获取字符串中所有指定的字串
    from re import findall# 提取message中金额对应的数字子串
    message = '我今年18岁,月薪50000元,身高180,体重70公斤,8快腹肌。每年交300元的腾讯会员费。房贷每月3000元,车贷每月2200元。'
    result = findall(r'(\d+)元',message)
    print(result)    # ['50000', '300', '3000', '2200']
    
分支 |

正则1|正则2|正则3|… - 匹配可以和多个正则中任意一个正则匹配的字符串

# 匹配一个字符串是三个数字或者两个小写字母:
result = fullmatch(r'\d{3}|[a-z]{2}','mk')
print(result)

注意:如果想要正则表达式中的一部分实现多选1的效果,变化的部分用分组表示

result = fullmatch(r'a\d{3}b|a[a-z]{3}b','a123b')
print(result)result = fullmatch(r'a(\d{3}|[a-z]{3})b','a123b')
print(result)

转义符号

  1. 转义符号

    正则中的转义符号,就是在本身具备特殊功能或者特殊意义的符号前加’\',让这个符号变成一个普通符号。

    # 匹配任意一个小数对应的字符串
    result = fullmatch(r'\d+\.\d+','23.879')
    print(result)# +234、+889111
    result = fullmatch(r'\+\d+','+23')
    print(result)# (mv)、(ksma)
    result = fullmatch(r'\([a-z]+\)','(msnd)')
    print(result)
    
  2. []里面的转义符号

    a. 单独存在有特殊意义的符号(+、*、?、.等),在[]中特殊意义会自动消失

    result = fullmatch(r'\d+[.+*?]d+','23?879')
    print(result)
    

    b. 本身在中括号中有特殊功能的符号,如果要表示普通符号必须加’\’

    result = fullmatch(r'a[MN-]b','a-b')
    print(result)result = fullmatch(r'a[M\-N]b','a-b')
    print(result)result = fullmatch(r'a[MN^]b','a^b')
    print(result)result = fullmatch(r'a[\^MN]b','a^b')
    print(result)
    

检测类符号

检测类符号是在匹配成功的情况下,检测检测类符号所在的位置是否符合相关要求

  1. \b - 检测是否是单词边界

    单词边界:可以将两个单词区分开的符号都是单词边界,比如:空白符号、英文标点符号、字符串开头和字符串结尾

    result = fullmatch(r'abc\b mn','abc mn')
    print(result)message = '203mn45,89 司机34kn;23;99mll==910,230 90='
    result = findall(r'\d+', message)
    print(result)       # ['203', '45', '89', '34', '23', '99', '910', '230', '90']result = findall(r'\d+\b', message)
    print(result)       # ['45', '89', '23', '910', '230', '90']result = findall(r'\b\d+', message)
    print(result)       # ['203', '89', '23', '99', '910', '230', '90']result = findall(r'\b\d+\b', message)
    print(result)       # ['89', '23', '910', '230', '90']
    
  2. \B - 检测是否不是单词边界

    message = '203mn45,89 司机34kn;23;99mll==910,230 90='
    result = findall(r'\B\d+\B', message)
    print(result)
    
  3. ^ - 检测是否是字符串开头

    message = '203mn45,89 司机34kn;23;99mll==910,230 90='
    result = findall(r'^\d+', message)
    print(result)# 提取字符串前5个字符
    message = '203mn45,89 司机34kn;23;99mll==910,230 90='
    result = findall(r'^.{5}', message)
    print(result)
    
  4. $ - 检测是否是字符串结尾

    # 提取字符串最后5个字符
    message = '203mn45,89 司机34kn;23;99mll==910,230 90='
    result = findall(r'.{5}$', message)
    print(result)
    

re模块常用函数

常用函数
  1. fullmatch(正则表达式,字符串) - 完全匹配,判断整个字符串是否符合正则表达式描述的规则,匹配成功返回匹配对象,匹配失败返回空

    result = fullmatch(r'\d{3}','234')
    print(result)
    
  2. match(正则表达式, 字符串) - 匹配字符串开头,判断字符串开头是否符合正则表达式描述的规则,匹配成功返回匹配对象,匹配失败返回空

    result = match(r'\d{3}', '823介绍数据库')
    print(result)
    
  3. search(正则表达式, 字符串) - 获取字符串中第一个能够和正则匹配的子串,能找到返回匹配对象,找不到返回空

    result = search(r'\d{3}', 'ba203还是678说')
    print(result)
    
  4. findall(正则表达式, 字符串) - 获取字符串中所有满足正则的子串,返回一个列表,列表中的元素是字符串。

    注意:如果正则表达式中有分组,会针对分组做自动捕获(只获取分组匹配到的结果)

    result = findall(r'\d{3}', 'ba203还是678说kk0222jksn就是23311')
    print(result)
    
  5. finditer(正则表达式, 字符串) - 获取字符串中所有满足正则的子串,返回一个迭代器,迭代器中的元素是每个子串对应的匹配对象

    result = finditer(r'\d{3}', 'ba203还是678说kk0222jksn就是23311')
    print(result)  # <callable_iterator object at 0x000002F163B64610>
    
  6. split(正则表达式, 字符串) - 将字符串中所有满足正则的子串作为切割点对字符串进行切割

    str1 = '123aMKnb嗑生嗑死aKKssa923b==='
    # 将str1中的a和b作为切割点对字符串进行切割
    result = split(r'a|b', str1)
    print(result)       # ['123', 'MKn', '嗑生嗑死', 'KKss', '923', '===']
    
  7. sub(正则表达式, 字符串1, 字符串2) - 将字符串2中所有满足正则的子串都替换成字符串1

    result = sub(r'\d+', '+', 'ba203还是678说kk0222jksn就是23311')
    print(result)
    
匹配对象
result = search(r'(\d{3})([A-Z]{2})','=j234KM77088897KH')
print(result)    # <re.Match object; span=(2, 7), match='234KM'>
  1. 直接获取整个正则表达式对应的匹配结果:匹配对象.group()

    print(result.group())    # '234KM'
    
  2. 手动捕获某个分组对应的匹配结果:匹配对象.group(分组数)

    print(result.group(1))   # '234'
    print(result.group(2))   # 'KM'
    
  3. 获取匹配结果在原字符串中的位置:匹配对象.span()

    print(result.span())    # (2, 7)
    print(result.span(2))   # (5, 7)
    
参数
  1. 匹配忽略大小写: (?i)

    result = fullmatch(r'(?i)abc', 'AbC')
    print(result)
    
  2. 单行匹配: (?s) (了解!)

    多行匹配(默认):匹配的时候.不能和换行(\n)进行匹配
    单行匹配:匹配的时候.可以和换行(\n)进行匹配

    result = fullmatch(r'abc.123', 'abc\n123')
    print(result)       # Noneresult = fullmatch(r'(?s)abc.123', 'abc\n123')
    print(result)       # <re.Match object; span=(0, 7), match='abc\n123'>
    

day17正则表达式相关推荐

  1. day-17正则表达式

    正则表达式 匹配类符号 什么是正则表达式 正则表达式是一种可以让复杂得字符串问题变得简单的工具 正则并不是python特有的语法(不属于python),所有的高级编程语言都支持正则,正则的语法通用 不 ...

  2. day17 正则表达式+今日作业

    八 正则表达式 正则表达式可以是一种可以让一些复杂字符串问题变得简单的工具. 8.1 匹配类符号 1.什么是正则表达式 正则表达式是一种可以让复杂的字符串问题变得简单的工具 正则并不是python特有 ...

  3. day17 正则表达式作业

    利用正则表达式完成下面的操作: 一.不定项选择题 能够完全匹配字符串"(010)-62661617"和字符串"01062661617"的正则表达式包括( ABD ...

  4. 21天Jmeter打卡Day17 后置处理器_JSON_正则表达式_边界提取器_完成删除场景模拟测试

    1天Jmeter打卡Day17 后置处理器_JSON_正则表达式_边界提取器_完成删除场景模拟测试 https://www.jianshu.com/p/5c1d64e5d724 Json提取器见Day ...

  5. Python学习:day21正则表达式

    写在前面: 此博客仅用于记录个人学习进度,学识浅薄,若有错误观点欢迎评论区指出.欢迎各位前来交流.(部分材料来源网络,若有侵权,立即删除) 传送门: day01基础知识 day02知识分类 day03 ...

  6. Python学习:day20正则表达式

    写在前面: 此博客仅用于记录个人学习进度,学识浅薄,若有错误观点欢迎评论区指出.欢迎各位前来交流.(部分材料来源网络,若有侵权,立即删除) 传送门: day01基础知识 day02知识分类 day03 ...

  7. Python学习Day17

    一.re模块import reprint(re.findall('alex','hahaha alex is alex is dsb'))['alex','alex']print(re.findall ...

  8. 通过正则表达式校验手机号码,拿走即用!

    校验手机号码 2021/01/06更新,电信新增了191号段 1. 单纯校验长度 2.正则表达式校验数字 3.正则表达式校验是否是大陆号码 4.正则表达式校验是否是香港号码 //校验长度private ...

  9. Linux shell 学习笔记(15)— shell 正则表达式

    1. 定义 BRE 模式 1.1 纯文本 第一条原则就是:正则表达式模式都区分大小写.这意味着它们只会匹配大小写也相符的模式. $ echo "This is a test" | ...

最新文章

  1. ++i 和 i++ 效率分析(C++)
  2. ViewResolvers
  3. 你可能不知道的.Net Core Configuration
  4. 数据结构06树和二叉树
  5. 运维人员mysql如何访问_mysql 运维常见操作
  6. php函数总结,php函数
  7. 搭建内网文件共享服务器,如何搭建共享服务器实现办公室文件共享?
  8. 圆柱螺旋压缩弹簧计算实例
  9. 防止javascript脚本读取cookie信息
  10. 学习软件技术的五大技巧
  11. ORACLE EBS常用表查询语句
  12. 【前端微服务化】使用飞冰搭建前端微服务化框架
  13. Day165/200 JS import * from 用法
  14. 王码五笔86版字根表图与字根助记词
  15. 云服务器安装并配置nginx
  16. 颜值爆表!华为发布新千元旗舰畅享6S
  17. Win7简易模拟Win10的开始页面
  18. ogg同步迁移数据库
  19. 使用 Python 分析《我不是药神》豆瓣电影短评
  20. 零拷贝、MMAP、堆外内存,傻傻搞不明白...

热门文章

  1. html制作计算器val,JavaScript实现的超简单计算器功能示例
  2. Vue实现简单计算器功能
  3. WMS手动配货和自动配货的区别
  4. 微信小程序音频相关问题:播放,录音等相关
  5. 使用ESP8266/ESP32 实现智能语音控制电脑开关机
  6. IO流处理2022-11-11
  7. office365 无法登录_WPS?Office2016,Office365到底有啥区别?
  8. Spring5学习笔记1
  9. 好看的某云易支付首页模板 open易支付程序
  10. 注册表中删除java