• python基础语法 - 正则表达式


    • 是什么:Regular Expression,简写RE,是预先定义好的一个“规则字符串”,通过这个规则字符串可以匹配、查找和替换那些符合规则的文本。
    • 优点:文本的查找替换虽然可以使用字符串提供的方法实现,但是实现较为困难,运算效率低。使用正则效率高。
    • 缺点:编写合适的正则表达式较为困难。
    • python中应用:数据挖掘、数据分析、网络爬虫、输入有效性验证等待。

    正则表达式字符串

    • 正则表达式是一种字符串,它由普通字符和元字符组成的。
    • 普通字符:按照字符字面意义的字符。
    • 元字符:预先定义好的一些特定字符。
    • 如验证邮箱的正则表达式:\w+@zhengzetang\.com,其中\w+\.属于元字符;@zhengzetangcom是普通字符。

    元字符

    • 用来描述其他字符的特殊字符,由基本元字符和普通字符构成,基本元字符是构成元字符的组成要素。基本元字符有14个,如下表在这里插入图片描述

    转义字符

    • 以上面匹配邮箱的字符串\w+@zhengzetang\.com为例
    • w字符不表示英文字母w,而是表示任何语言的单词字符、数字或下划线等内容时,需要在w前面加上反斜杠“\”。
    • .本身是基本元字符,代表任意一个字符,但是我们希望按照.字面的意义使用(就是一个点),这时候加上一个反斜杠“\”就可以实现了。
    • 转义字符\就是对普通字符或基本元字符,进行转义,用于其他功能。

    开始与结束符

    • 前面提到了^$,用以匹配一行字符串的开始和结束。
    • 当以^开始时,要求一行字符串的开始位置匹配。
    • 当以$结束时,要求一行字符串的结束位置匹配。
      import re 
      
      p1 = r'\w+@tianshangrenjian\.com'
      p2 = r'^\w+@tianshangrenjian\.com$'
      
      text = "My email is tong_guan588@tianshangrenjian.com."
      m = re.search(p1, text)
      print(m)
      
      # 匹配不到,有^,$符号,匹配时要求text字符串开始和结束都要与正则表达式开始和结束匹配。
      a = re.search(p2,text)
      print(a)
      
      # email字符串的开始与结束与正则表达式相匹配
      email = 'tong_guan588@tianshangrenjian.com'
      b = re.search(p2, email)
      print(b)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
    • 显示结果
      在这里插入图片描述

    字符类

    • 正则表达式种可以使用字符类(character class),一个字符类定义一组字符,其中的任一字符出现在输入字符串中即匹配成功。
    • 注意:每次匹配只能匹配字符串中的一个字符。

    定义字符类

    • 定义一个普通的字符类,使用[]元字符类。例,想在字符串中匹配java或Java,可以使用正则表达式[Jj]ava
      import re
      
      p = r'[Jj]ava'
      
      # 可以匹配
      m = re.search(p, 'i like Java and Python')
      print(m)
      
      # 可以匹配
      c = re.search(p, 'i like java and Python')
      print(c)
      
      # 不可匹配
      b = re.search(p, 'i like JAVA and Python')
      print(b)
      
      # 想要匹配JAVA,可以使用|
      p2 = r'java|JAVA|Java'
      d = re.search(p2, 'i like JAVA and Python')
      print(d)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
    • 运行结果为
      在这里插入图片描述

    字符类取反

    • 在正则表达式中指定不想出现的字符, 可以在字符前加^符号。
      import re 
      
      p = r'[^0123456789]'
      
      # 不匹配数字
      m = re.search(p, '239120392')
      print(m)
      
      # 除了非数字外,都可以匹配任意字符
      a = re.search(p, 'Reasdskf')
      print(a)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • 运行结果
      在这里插入图片描述

    区间

    • 如果要表示连续的数字,用[^0123456789],较为复杂,可以使用区间符号-表示。即[^0123456789]等同于[^0-9]
    • 连续的英文字母可以表示为[a-z],大写[A-Z]
    • 可以表示多个不同区间,如[A-Za-z0-9]表示所有字母和数字字符类,[0-25-7]表示0,1,2,5,6,7
      import re 
      
      p = r'[a-zA-Z0-9]'
      
      # 匹配
      m = re.search(p, 'A10.3')
      print(m)
      
      # 不匹配
      a = re.search(r'[0-25-7]', 'A3489C')
      print(a)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

    预定义字符类

    • 有些字符很常用,如[0-9]等,为了书写方便,正则表达式提供了预定义的字符类。
      在这里插入图片描述
    • 示例
      import re
      
      # p = r'[^0123456789]'
      p = r'\D'
      
      # 不匹配
      m = re.search(p, '11003')
      print(m)
      
      # 匹配
      a = re.search(p, 'ajdka')
      print(a)
      
      text = "hello world。"
      b = re.search(p, text)
      print(b)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    • 运行结果
      在这里插入图片描述

    量词

    • 上面说的正则,只能匹配显示一次字符或字符串,如果想匹配显示多次字符或字符串可以使用量词。

    量词的使用

    • 量词表示字符或字符串重复的次数,量词如下表
    字符说明
    ?出现零次或一次
    *出现零次或多次
    +出现一次或多次
    {n}出现n次
    {n, m}至少出现n次但不超过m次
    {n, }至少出现n次
    • 示例
      import re
      
      m = re.search(r'\d?', '87654321')   # 出现数字一次,匹配字符8
      print(m)
      
      a = re.search(r'\d?', 'adxcx')      # 出现数字0次,匹配''
      print(a)
      
      b = re.search(r'\d*', '2134354afas123') # 出现数字多次,匹配2134354
      print(b)
      
      c = re.search(r'\d{8}', '87654321')     # 出现数字8次,匹配87654321
      print(c)
      
      d = re.search(r'\d{9,}', '87654321')    # 出现数字8次,但要求9次,不匹配
      print(d)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    • 运行结果
      在这里插入图片描述

    贪婪和懒惰

    • 量词细分为贪婪量词和懒惰量词。
    • 贪婪量词会尽可能多地匹配字符,懒惰量词会尽可能少地匹配字符。
    • 大多数计算机语言的正则表达式词默认是贪婪的,要想使用懒惰量词在量词后面加 ?
      import re
      
      # 使用贪婪量词
      m = re.search(r'\d{5,8}', '87456123')   # 至少出现5次,不少于8次,贪婪匹配8次
      print(m)
      
      # 使用懒惰量词
      a = re.search(r'\d{5,8}?', '87456123')  # 懒惰匹配5次
      print(a)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    • 运行结果
      在这里插入图片描述

    分组

    • 分组也称为子表达式,就是将一个字符串放到一对小括号中,让一个字符串作为整体使用量词。

    分组的使用

    • 对正则分组不仅可以对一个字符串整体使用量词,也可以在正则中引用已存在的分组。

    • 示例

      import re
      
      p = r'(121){2}'
      m = re.search(p, '121121121adfd')   # 匹配121121
      print(m)
      print(m.group())    # 返回匹配的字符串
      print(m.group(1))   # 返回第一组内容
      
      a = r'(\d{3,4})-(\d{7,8})'
      b = re.search(a, '010-7785457322a')
      print(b)
      print(b.group())
      print(b.group(1))
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    • 运行结果
      在这里插入图片描述

    分组命名

    • 组命名:在组开头添加?P<分组名>
    • 分组命名后,方便程序访问分组。
    • 示例
      import re
      
      p = r'(?P\d{3,4})-(?P\d{7,8})'
      
      b = re.search(p, '010-77548573')
      print(b)
      print(b.group())
      print(b.groups())
      
      # 通过组编号返回
      print(b.group(1))
      print(b.group(2))
      
      # 通过组名返回
      print(b.group('area_code'))
      print(b.group('phone_code'))
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    • 运行结果
      在这里插入图片描述

    反向引用分组

    非捕获分组

    • 捕获分组:匹配子表达式的结果被暂时保存到内存中,以备表达式或其他程序使用,这个过程就是“捕获”,捕获结果可以通过组编号或组名进行引用。
    • 非捕获分组:与上面相反,不想存,不想引用,只是单纯的匹配。
    • 实现方法:组开头使用?:
      import re
      
      s = 'img1.png, img2.png, img3.jpg, img4.png'
      
      # 捕获分组,将括号中的内容作为子表达式进行捕获匹配,将组的内容返回
      p1 = r'\w+(\.png)'
      mlist = re.findall(p1,s)
      print(mlist)
      
      # 非捕获分组,将括号中的内容作为普通正则字符串进行整体匹配,即找到.png结尾的文本
      p2 = r'\w+(?:\.png)'
      nlist = re.findall(p2,s)
      print(nlist)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    • 运行结果
      在这里插入图片描述

    re模块

    • re模块是python内置的正则表达式模块。

    search()和match()函数

    • 两者非常相似, 区别如下:
      • search():在输入字符串中查找,返回第一个匹配内容,找到就匹配对象,没找到就返回None
      • match():在输入字符串开始处查找匹配内容,找到就匹配对象,没找到就返回None
    • 示例
      import re
      
      p = r'\w+@woaipython\.com'
      
      text = 'my email is coucher42@woaipython.com'
      # 能匹配
      m = re.search(p,text)
      print(m)
      
      # 不能匹配
      n = re.match(p,text)
      print(n)
      
      email = 'coucher42@woaipython.com'
      # 能匹配
      a = re.search(p,email)
      print(a)
      
      # 能匹配
      b = re.match(p, email)
      print(b) 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
    • 运行结果
      在这里插入图片描述
    • match对象的几个方法:
      email = 'coucher42@woaipython.com'
      b = re.match(p, email)
      print(b)
      print(b.group())
      print(b.start())
      print(b.span())
      print(b.end())
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    • 运行结果
      在这里插入图片描述

    findall()和finditer()函数

    • 两者相似,区别如下:
      • findall():在输入字符串中查找所有匹配内容,如果匹配成功,返回match列表对象,否则返回None。
      • finditer():在输入字符串中查找所有匹配内容,如果匹配成功,返回容纳match的可迭代对象,通过迭代对象每次可以返回一个match对象,如果失败则返回None。
      import re
      
      p = r'[Pp]ython'
      text = 'i like python or Python.'
      
      match_list = re.findall(p, text)
      print(match_list)
      
      match_iter = re.finditer(p, text)
      for i in match_iter:
          print(i)
          print(i.group())
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
    • 运行结果

    字符串分割

    • 函数split(),按照匹配的子字符串进行分割,返回字符串列表对象。
    • 构造方式:re.split(pattern, string, maxsplit=0, flags=0)
    • pattern:正则表达式
    • string:要分割的字符串
    • maxsplit:最大分割次数,默认为0,意味着分割次数没有限制
    • flags:编译标志。
      import re
      p = r'\d+'
      text = 'ABCD12EF33gh'
      
      clist = re.split(p, text)
      print(clist)
      
      dlist = re.split(p, text, maxsplit=1)
      print(dlist)
      
      elist = re.split(p, text, maxsplit=2)
      print(elist)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
    • 运行结果
      在这里插入图片描述

    字符串替换

    • 函数sub(),用于替换匹配的字符串,返回值是替换之后的字符串。
    • 构造方式:re.sub(pattern, repl, string, count=0, flags=0)
    • pattern:正则表达式
    • repl:要替换字符串
    • string:要提供的字符串
    • count:要替换的最大数量,默认为0,意味着替换没有次数
    • flags:编译标志
      import re 
      p = r'\d+'
      text = 'ABCD12EF33gh'
      
      replace_text = re.sub(p, ' ', text)
      print(replace_text)
      replace_text = re.sub(p, ' ', text, count=1)
      print(replace_text)
      replace_text = re.sub(p, ' ', text, count=2)
      print(replace_text)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    • 运行结果
      在这里插入图片描述
  • 相关阅读:
    正向代理和反向代理快速理解
    fastapi+mongo+qlib:体系化构建AI量化投研平台
    Ubuntu16.04 python matplotlib 输出轴标签出现中文乱码
    【计算机网络】概述 习题
    Python使用总结之PyInstaller常用参数详解
    springboot+jsp+ssm高校图书馆图书借阅收藏评论管理系统617w1
    gdb调试插件的安装——gef/gdbinit/peda(记录向)
    理解JS函数之call,apply,bind
    关于过滤链设计的实践记录
    推荐《咒术回战》
  • 原文地址:https://blog.csdn.net/Cherish1ove/article/details/126211286