re模块

Posted abner28

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了re模块相关的知识,希望对你有一定的参考价值。

re模块

  • 负责处理正则表达式的模块

  • 什么是正则表达式?

    • 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。
  • 正则表达式的使用场景

    1. 判断某个字符串是否符合规则 用户注册页面—表单验证
    2. 将符合规则的内容从一个庞大的字符串体系当中提取出来 爬虫、日志分析
  • 元字符

    1. 字符组
      • 在字符组中所有的字符都可以匹配任意一个字符位置上能出现的内容,如果在字符串中有任意一个字符是字符串的内容,那么就是符合匹配要求的项

      • 格式:[],匹配中括号内的字符

        import re
        ret = re.search(‘[abc]‘,‘a‘)
        print(ret)
        输出:
        <_sre.SRE_Match object; span=(0, 1), match=‘a‘>
      • 通过上述结果表明‘a’是满足这个元字符正则表达式的。

    2. 字符
      元字符 匹配结果
      . 匹配除了 的所有字符
      w 匹配数字、字母、下划线
      s 匹配空字符,包括空格符、换行符、制表符
      d 匹配0-9的数字
      匹配一个换行符
      匹配一个制表符
       匹配单词的边界在前为匹配开头,在后为匹配结尾
      W 匹配除了数字、字母、下划线之外的所有字符
      S 匹配除了空字符,包括空格符、换行符、制表符的字符
      D 匹配除了0-9的数字的字符
      B 匹配单词中间包含,不匹配首尾
      ^ 匹配开始标识符
      $ 匹配结尾标识符
      a|b 匹配字符串为a字符或者为b字符
      () 匹配括号内的表达式,也代表一个组
      [...] 匹配字符组中的字符
      [^...] 匹配除了字符组中的所有字符
      ‘的实际用法:判断多个单词,将以ing结尾的单词取出‘
      import re
      string = "sing 1studing studing1 swimming"
      ret = re.findall(r"[a-zA-Z]*ing",string)
      print(ret)
      输出:
      [‘sing‘, ‘swimming‘]
      
      ‘[^...]的实际用法:取出多层算式的最内层括号的所有值,1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))‘
      import re
      s = ‘1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))‘
      ret = re.findall(r‘([^()]+)‘,s)
      print(ret)
      输出:
      [‘(-40/5)‘, ‘(9-2*5/3+7/3*99/4*2998+10*568/14)‘, ‘(-4*3)‘, ‘(16-3*2)‘]
  • 量词

    • 量词必须跟在元字符后,并且通常只能约束一个元素

    • 注意:由分组括起来的元素算一个元素

      import re        #程序一
      ret = re.search(‘(asd)*‘,‘as1as2as3‘)
      print(ret)
      输出:
      <_sre.SRE_Match object; span=(0, 9), match=‘as1as2as3‘>
      
      ret = re.search(‘(asd)*‘,‘as1a2as3‘)           #程序二
      print(ret)
      输出:
      <_sre.SRE_Match object; span=(0, 3), match=‘as1‘>
      • 上述的程序唯一的区别在于字符串由‘as1as2as3’改为了‘as1a2as3’,但是匹配结果就发生了差异,由于程序一中匹配的字符串as1as2as3都满足正则表达式,所以*将他们全部匹配到了,而程序二中因为删除掉了一个as2的s所以程序中只能匹配到as1
      量词 使用方法
      * 重复0次或更多次
      + 重复1次或更多次
      ? 重复0次或1次
      {n} 重复n次
      {n,} 重复n次或更多次
      {n,m} 重复n次到m次
  • 贪婪匹配:正则会尽量多的匹配

    • 默认贪婪 回溯算法
  • 非贪婪匹配:会尽力少的匹配

    • 默认算法 惰性算法
    • .*?x 遇到x立即停止
    import re             #程序一
    s = "<script> alog(‘speed.set‘, ‘ht‘, +new Date); </script>"
    ret = re.findall(‘<.*>‘,s)
    print(s)
    输出:
    ["<script> alog(‘speed.set‘, ‘ht‘, +new Date); </script>"]
    
    import re         #程序二
    s = "<script> alog(‘speed.set‘, ‘ht‘, +new Date); </script>"
    ret = re.findall(‘<.*?>‘,s)
    print(ret)
    输出:
    [‘<script>‘, ‘</script>‘]
    • 上述输出第一个程序为贪婪匹配,第二个程序为非贪婪算法,上述的贪婪匹配算法在第一次匹配到>时并没有停止,因为根据*的量词规则,会尽可能多的去匹配字符,所以会匹配最后的那个>,而在第二个程序中添加了一个?,所以只会匹配第一个>,所以可以得出两个元素。

    • 补充非贪婪匹配:

      量词组 匹配规则
      *? 重复任意次,但尽可能少重复
      +? 重复1次或更多次,但尽可能少重复
      ?? 重复0次或1次,但尽可能少重复
      {n,m}? 重复n到m次,但尽可能少重复
      {n,}? 重复n次以上,但尽可能少重复
  • 转义符

    • 在Python中应用,在正则表达式和字符串前加r就可以解决所有的转移问题

re模块使用方法

  1. re.findall

  • 参数:正则表达式,带匹配字符串

  • 返回值:一个包含所有匹配项列表

  • 注意:findall会优先显示分组中的内容,如果需要结果的全部取到,必须取消分组优先,在分组前加?:

    import re
    ret = re.findall(‘d‘,‘2138725876358‘)
    print(ret)
    输出:
    [‘2‘, ‘1‘, ‘3‘, ‘8‘, ‘7‘, ‘2‘, ‘5‘, ‘8‘, ‘7‘, ‘6‘, ‘3‘, ‘5‘, ‘8‘]
    import re
    ret = re.findall(‘www.(baidu|hao123).com‘,‘www.baidu.com‘)
    print(ret)
    输出:
    [‘baidu‘]      #优先匹配分组的内容
    #希望显示全部内容,只需要在分组括号的首部加入?:
    ret = re.findall(‘www.(?:baidu|hao123).com‘,‘www.baidu.com‘)
    print(ret)
    输出:
    [‘www.baidu.com‘]
  1. re.search

    • 参数:正则表达式,带匹配字符串

    • 返回值:一个match对象,通过返回值.group(),得到一个值,且只包含第一个匹配到的值

    • 注意:在使用search之前,必须对返回值进行判断是否存在,即是否在字符串中是否找到。

      import re
      ret = re.search(‘(www).(baidu|hao123).(com)‘, ‘www.baidu.com‘)
      print(ret.group(0))
      print(ret.group(1))
      print(ret.group(2))
      print(ret.group(3))
      输出:
      www.baidu.com
      www
      baidu
      com
      #由此可以得出全部分组数据可以根据group(n)来得到,其中group(0)和group()等价会将整体输出。

补充:findall和search的分组区别

  1. findall会优先显示分组中的内容,如果需要结果的全部取到,必须取消分组优先,在分组前加?:
  2. search通过group()可以取到匹配的完整值,可以根据group(n)取出正则表达式中的各个分组的值。

以上是关于re模块的主要内容,如果未能解决你的问题,请参考以下文章

python 正则表达式 re模块基础

如何使用模块化代码片段中的LeakCanary检测内存泄漏?

Python基础之re模块

如何有条件地将 C 代码片段编译到我的 Perl 模块?

python re模块findall()详解

Node.js JavaScript 片段中的跳过代码