• 基础语言-第17天-正则表达式


    正则表达式

    一、定义

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

    注意:所有的高级编程语言都支持正则,正则的语法通用。不是Python特有的。

    二、匹配类符号

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

      fullmatch(正则表达式, 字符串)

      判断正则表达式和指定的字符串是否完全匹配。(判断字符串是否符合正则表达式描述的规则)
      匹配成功返回匹配对象,匹配失败返回None。
      
      • 1
      • 2
      # 导入re模块中的fullmatch方法
      from re import fullmatch
      
      • 1
      • 2
    • 匹配类符号语法

      1)普通符号:正则表达式表达符号本身的符号。
      2).:匹配任意一个字符
      3)\d:匹配任意一个数字字符
      4)\s:匹配任意一个空白字符
      5)\D:匹配任意一个非数字字符
      6)\S:匹配任意一个非空白字符
      7)[字符集]:匹配字符集中任意一个字符
      	[abc] - 匹配a或者b或者c
      	[abc\d] - 匹配a或者b或者c或者任意一个数字
      	[1-9] - 匹配1-9中任意一个数字
      	[a-z] - 匹配任意一个小写字母
      	[A-Z] - 匹配任意一个大写字母
      	[a-zA-Z\d_] - 匹配字母数字或者下划线
      	[\u4e00-\u9fa5] - 匹配任意一个中文字符
      
      	注:[]中减号放在两个字符之间表示谁到谁(确定的方式是根据字符编码值大小确定的);如果减号不在两个字符之间表示普通的减号。
      
      8)[^字符集]:匹配不在字符集中任意一个字符,^只能放在最前面
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      from re import fullmatch
      
      # 1)普通符号:正则表达式表达符号本身的符号。
      result = fullmatch(r'abc', 'abc')
      print(bool(result))   # True
      
      # 2).  -  匹配任意一个字符
      result = fullmatch(r'a.c', 'acc')
      print(bool(result))   # True
      
      # 3)\d  -  匹配任意一个数字字符
      result = fullmatch(r'a\dc', 'a0c')
      print(bool(result))   # True
      
      # 4)\s  -  匹配任意一个空白字符
      # 空白字符  -  能产生空白效果的字符,例如:空格、换行、水平制表符
      result = fullmatch(r'a\sc', 'a c')
      print(bool(result))   # True
      
      result = fullmatch(r'a\sc', 'a\tc')
      print(bool(result))   # True
      
      result = fullmatch(r'a\sc', 'a\nc')
      print(bool(result))   # True
      
      # 5)\D  -  匹配任意一个非数字字符
      result = fullmatch(r'a\Dc', 'abc')
      print(bool(result))   # True
      
      # 6)\S  -  匹配任意一个非空白字符
      result = fullmatch(r'a\Sc', 'a c')
      print(bool(result))    # False
      
      # 7)[字符集]:匹配字符集中任意一个字符
      result = fullmatch(r'x[a-zA-Z\u4e00-\u9fa5-]h', 'x-h')
      print(bool(result))   # True
      
      # 8)[^字符集]:匹配不在字符集中任意一个字符,^只能放在最前面
      result = fullmatch(r'x[^\d]h', 'x是h')
      print(bool(result))   # True
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40

    三、匹配次数

    • *: 0次或多次(任意次数);

      :星号在谁后面控制谁的次数

      result = fullmatch(r'a*123', '123')
      print(bool(result))  # True
      
      result = fullmatch(r'a*123', 'aaaa123')
      print(bool(result))  # True
      
      • 1
      • 2
      • 3
      • 4
      • 5
    • +:1次或者多次(至少一次)

      result = fullmatch(r'[MN]+abc', 'abc')
      print(bool(result))  # False
      
      result = fullmatch(r'[MN]+abc', 'MNNMabc')
      print(bool(result))  # True
      
      • 1
      • 2
      • 3
      • 4
      • 5
    • ?:0次或1次

      result = fullmatch(r'A?abc', 'abc')
      print(bool(result))  # True
      
      result = fullmatch(r'A?abc', 'Aabc')
      print(bool(result))  # True
      
      result = fullmatch(r'A?abc', 'AAabc')
      print(bool(result))  # False
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    • {}

      {M,N}    -    M到N次
      {M,}    -    至少M次
      {,N}    -    最多N次
      {N}    -    N次
      
      • 1
      • 2
      • 3
      • 4
      result = fullmatch(r'[a-z]{3,5}123', 'asdf123')
      print(bool(result))    # True
      
      result = fullmatch(r'[a-z]{3,}123', 'asdfssss123')
      print(bool(result))    # True
      
      result = fullmatch(r'[a-z]{,5}123', 'asdf123')
      print(bool(result))    # True
      
      result = fullmatch(r'[a-z]{3}123', 'asdf123')
      print(bool(result))    # False
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • 贪婪和非贪婪

      当匹配次数不确定(*、+、?、{M,N}、{M,}、{,N})时,匹配模式分为贪婪和非贪婪两种。默认贪婪。
      
      • 1
      1.贪婪:匹配成功时有多种匹配结果,贪婪取最多次数对应的匹配结果。
            (匹配次数不确定的地方,有多种匹配方式都可以匹配成功,贪婪取最多次数)
      贪婪模式:*、+、?、{M,N}、{M,}、{,N}
      
      • 1
      • 2
      • 3
      # 贪婪
      result = match(r'a.+b', 'amb互换bfjbmi')
      print(result)    # match='amb互换bfjb'
      
      # 注意:如果匹配结果只有一种可能,贪婪和非贪婪的结果一样。
      # 贪婪
      result = match(r'a.+b', 'amb互换')
      print(result)    # match='amb'
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      2.非贪婪:匹配成功时有多种匹配结果,贪婪取最少次数对应的匹配结果。
            (匹配次数不确定的地方,有多种匹配方式都可以匹配成功,贪婪取最少次数)
      
      非贪婪模式:*?、+?、??、{M,N}?、{M,}?、{,N}?
      
      • 1
      • 2
      • 3
      • 4
      # 非贪婪
      result = match(r'a.*?b', 'amb互换bfjbmi')
      print(result)    # match='amb'
      
      # 注意:如果匹配结果只有一种可能,贪婪和非贪婪的结果一样。
      # 贪婪
      result = match(r'a.+b', 'amb互换')
      print(result)    # match='amb'
      
      # 非贪婪
      result = match(r'a.*?b', 'amb互换')
      print(result)    # match='amb'
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12

    四、分组和分支

    • 分组

      1)整体:将正则表达式中的一部分作为一个整体进行相关操作。
      2)重复:可以在正则表达式中通过\M来重复它前面的第M个分组的匹配结果。
              不能重复\M之后出现的内容(否则会报错!)。
      3)捕获:只获取正则表达式中分组的一部分匹配到的结果(分为手动和自动捕获两种)
      
      • 1
      • 2
      • 3
      • 4
      # 导入fullmatch模块和findall模块
      from re import fullmatch, findall
      
      # 2.重复
      # 例子1:两个数字两个大写字母重复
      result = fullmatch(r'(\d\d[A-Z]{2})+', '22WE35SD')
      print(result)
      
      # 例子2:23d23 45t45
      result = fullmatch(r'(\d{2})[a-z]\1', '45t45')
      print(result)
      
      # 例子3:23dfg=dfg232323(重复两个分组)
      result = fullmatch(r'(\d{2})([a-z]{3})=\2\1{3}', '23dfg=dfg232323')
      print(result)
      
      # 3.捕获
      message ='我今年18岁,月薪50000元,身高180,体重70公斤,8块腹肌。每年交300元的腾讯会员费。房贷每月3000元,车贷每月2280元。'
      result = findall(r'(\d+)元',message)
      print(result)   # ['50000', '300', '3000', '2280']
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
    • 分支:|(或者)

      正则1|正则2|正则3|...:匹配可以和多个正则中任意一个正则匹配的字符串。
      
      • 1
      # 例子
      # 匹配三个数字或两个字母
      result = fullmatch(r'\d{3}|[a-z]{2}', 'ed')
      print(bool(result))    # True
      
      # a两个数字d、a三个字母d
      # 注:如果想要正则表达式中的一部分实现多选一功能,变化的部分用分组表示。
      result = fullmatch(r'a(\d{3}|[a-z]{2})d', 'a123d')
      print(bool(result))    # True
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

    五、转义符号

    • 转义符号

      在本身具备特殊功能或特殊意义的符号前加'\',让这个符号变成普通符号。
      
      • 1
      # .具备特殊意义,所以前面加个\
      result = fullmatch(r'\d+\.\d+', '23.89')
      print(bool(result))    # True
      
      # +具备特殊意义
      result = fullmatch(r'\+\d+', '+123329')
      print(bool(result))    # True
      
      # ()具备特殊意义
      result = fullmatch(r'\([A-Z]+\)', '(ASJDSJI)')
      print(bool(result))    # True
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • []里的转义符号

      1)单独存在有特殊意义的符号(+、*、?、.等),在[]中特殊意义会自动消失。
      2)本身在中括号中有特殊功能的符号(-、^),如果表示普通符号必须加'\'。
      
      • 1
      • 2
      # 1)单独存在有特殊意义的符号(+、*、?、.等),在[]中特殊意义会自动消失
      result = fullmatch(r'\d+[.+*?]\d+', '433?444')
      print(bool(result))    # True
      
      # 2)本身在中括号中有特殊功能的符号(-、^),如果表示普通符号必须加'\'
      result = fullmatch(r'a[M\-N]b', 'a-b')  # -
      print(bool(result))    # True
      
      result = fullmatch(r'a[\^MN]b', 'a^b')   # ^
      print(bool(result))    # True
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10

    六、检测类符号

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

    • \b: 检测是否是单词边界

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

      result = fullmatch(r'abc\b mn', 'abc mn')
      print(result)  # √
      
      message = '203mn45,89 四级45kn;23;09mll==333,234 89='
      result = findall(r'\d+', message)
      print(result)    # ['203', '45', '89', '45', '23', '09', '333', '234', '89']
      
      result = findall(r'\d+\b', message)   # 右
      print(result)  # ['45', '89', '23', '333', '234', '89']
      
      result = findall(r'\b\d+', message)    # 左
      print(result)   # ['203', '89', '23', '09', '333', '234', '89']
      
      result = findall(r'\b\d+\b', message)    # 左、右都有
      print(result)    # ['89', '23', '333', '234', '89']
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
    • \B: 检测是否不是单词边界

      message = '203mn45,89 四级45kn;23;09mll==333,234 89='
      result = findall(r'\B\d+\B', message)
      print(result)    # ['03', '4', '45', '9', '3', '3']
      
      • 1
      • 2
      • 3
    • ^: 检测是否是字符串开头

      message = '203mn45,89 四级45kn;23;09mll==333,234 89='
      result = findall(r'^\d+', message)
      print(result)    # ['203']
      
      # 提取字符串前十个字符
      message = '203mn45,89 四级45kn;23;09mll==333,234 89='
      result = findall(r'^.{10}', message)
      print(result)    # ['203mn45,89']
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    • $: 检测是否是字符串结尾

      # 提取字符串后十个字符
      message = '203mn45,89 四级45kn;23;09mll==333,234 89='
      result = findall(r'.{10}$', message)
      print(result)    # ['33,234 89=']
      
      • 1
      • 2
      • 3
      • 4

    七、re模块常用函数

    • 函数

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

      2.match(正则表达式,字符串): 匹配字符串开头,判断字符串开头是否符合正则表达式描述的规则。

      3.search(正则表达式,字符串): 获取字符串中第一个能够和正则表达式匹配成功的子串。

      4.findall(正则表达式,字符串): 获取字符串中所有满足正则表达式的子串,返回一个元素为字符串的列表;没有则为[]。

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

      5.finditer(正则表达式,字符串): 获取字符串中所有满足正则表达式的子串,返回一个迭代器,迭代器中的元素是每个子串对应的匹配结果。

      6.split(正则表达式,字符串): 将字符串中所有满足正则的子串作为切割点对字符串进行切割。

      str1 = '123aMNnb看的价位aIIeea990b=='
      print(str1.split('a'))    # ['123', 'MNnb看的价位', 'IIee', '990b==']
      
      # 将a、b作为切割点
      result = split(r'a|b', str1)
      print(result)    # ['123', 'MNn', '看的价位', 'IIee', '990', '==']
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      7.sub(正则表达式,字符串1,字符串2):将字符串2中所有满足正则的子串都替换成字符串1。

      result = sub(r'\d+', '+', '123aMNnb看的价位aIIeea990b==')
      print(result)    # +aMNnb看的价位aIIeea+b==
      
      • 1
      • 2
    • 匹配对象

      result = search(r'(\d{3})([A-Z]{3})', '233SDD556WER')
      print(result)    # 
      
      • 1
      • 2

      1.匹配对象.group(): 直接获取整个正则表达式对应的匹配结果。

      print(result.group())    # 233SDD
      
      • 1

      2.匹配对象.group(分组数): 手动捕获某个分组对应的匹配结果。

      print(result.group(1))    # 233
      print(result.group(2))    # SDD
      
      • 1
      • 2

      3.匹配对象.span(): 获取指定结果在原字符串中的位置。

      print(result.span())    # (0, 6)
      print(result.span(2))   # (3, 6)
      
      • 1
      • 2
    • 参数

      1.匹配忽略大小写: (?i)写在正则表达式前面。

      result = fullmatch(r'(?i)abc', 'ABc')
      print(result)    # 
      
      • 1
      • 2

      2.单行匹配: (?s)写在正则表达式最前面。

      多行匹配(默认):匹配时.不能和'\n'进行匹配
      单行匹配:匹配时.可以和'\n'进行匹配
      
      • 1
      • 2
      # 多行
      result = fullmatch(r'abc.123', 'abc\n123')
      print(result)    # None
      
      # 单行
      result = fullmatch(r'(?s)abc.123', 'abc\n123')
      print(result)    # 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
  • 相关阅读:
    Linux驱动之INPUT设备驱动
    MacOS 控制固态磁盘写入量,设置定时任务监控
    深度学习 Day 17——利用卷神经网络实现猫狗识别
    (JavaSE) 数组
    重写 equals 方法,实现比较两个对象值是否相等
    基于springboot实现教师人事档案管理系统项目【项目源码+论文说明】计算机毕业设计
    微源股份冲刺上市:上半年利润下滑六成,戴兴科夫妇为实控人
    (整理)蓝屏代码对应原因_蓝屏问题解决方法
    【数据结构-树】并查集的定义及其操作
    智能微型断路器应该怎么选型?
  • 原文地址:https://blog.csdn.net/simple_daytime/article/details/126255564