zoukankan      html  css  js  c++  java
  • python常用模块——re

    re 正则匹配模块

    一、元字符:

        .       通配符,匹配任意一个字符(
    除外)
    
        ^       开头
    
        $       结尾
    
        *       重复匹配,重复前面的字符0个或多个;
           	    特殊情况:
        		  import re
        		  ret = re.findall('7*','efe')
        		  print(ret)                   # 输出['', '', '', '']  因为*可以为0个或多个。后面字符串中,每个字符前后都有0个7; 
        
        +	    重复匹配,重复前面的字符1个或多个;
        
        ?	    重复匹配,重复前面的字符0个或一个字符
    
        {}	    重复匹配,重复前面的字符指定的次数
        	    例如:
        		  import re
        		  ret = re.findall('a{3}b','aaaab')
        		  print(ret)		      # 输出 ['aaab']     重复3次a;这里也可以匹配范围,如 a{1,3} 即重复1到3次;{1,}表示1到无穷次;
    
        []      字符集;表示范围,或的关系;同时,取消元字符的特殊意义,将元字符变为普通字符(有三个例外  ^ -);[]中的^是取反的意思;反斜杠后面跟普通字符来实现特殊功能的字符可以使用在[]里,例如 [d] 表示0-9的数字;
                例如:
                    a[cde]h         表示 ach或adh或aeh
                    [a-z]           表示小写字母a到z
                    [0-9a-zA-Z]     表示数字、大小写字母
                    [^456]          表示非4,非5 和 非6;即所有的项都取反
    
        |       管道符,表示或者;
    
    
               反斜杠;
                反斜杠后面跟元字符,去除元字符的特殊功能;即转义;
                    例如:
                        import re
                        ret1 = re.findall('*','hello*ok')        #* 来表示 *号本身,而不是通配符;
                        ret2 = re.findall('\\','hellook')      #\\ 表示 ;在python解释器中解释时,反斜杠需要转义,传给re模块后,re模块中的正则也需要转义;故这里的\\给正则时相当于 \;
                        ret3 = re.findall(r'\','hellook')       # 行显示,表示后面字符串没有特殊意义;和上面\\效果一样;
    
                反斜杠后面跟普通字符,实现特殊功能;  
                    如下:
                        d  匹配任何十进制数;相当于 [0-9]
                        D  匹配任何非数字字符;相当于[^0-9]
                        s	匹配任何空白字符;相当于 [ 	
    
    fv];	前面是空格
                        S	匹配任何非空白字符;相当于 [^ 	
    
    fv]; 	前面是空格
                        w	匹配任何字母数字字符;相当于 [a-zA-Z0-9_]
                        W	匹配任何非字母数字字符;相当于 [^a-zA-Z0-9_]
                        	匹配一个单词边界,也就是指单词和空格间的位置
                    例如:
                        import re
                        ret = re.findall(r'I','Hello,I am a LIST.')
                        print(ret)          # 输出 I am 这个 I;会检测单词的边界;即字母的边界如果是特殊字符,则认为该字母是一个单词;但是有例外,如这里假如一个单词,结尾是I,则也会匹配到。
    
        ()      分组;注意分组在findall方法中的使用,见findall方法处;
                例如:
                    import re
                    ret = re.findall('(as)+','sfefeffeasasas')
                    print(ret)                  # 输出 ['as']
                    ret1 = re.search('(as)+','sfefeffeasasas').group()
                    print(ret1)                 # 输出 asasas
    
    

    二、 正则表达式re模块常用方法

    1. findall()

    所有匹配的结果都返回到一个列表中;findall中使用分组时,只返回分组所匹配的内容;当分组外面使用+等符号时,只打印最后一次匹配到的(如下面的ret1、ret2);
    分组的优先级高于普通的匹配,如果想都匹配,可以使用?:来改变优先级;
    例如:
        import re
        ret1 = re.findall('www.(w)+.com','www.bashrunning.com')
        ret2 = re.findall('www.(w)(w)+.com','www.bashrunning.com')
        ret3 = re.findall('www.(w+).com','www.bashrunning.com')
        ret4 = re.findall('www.(w)(w+).com','www.bashrunning.com')
        ret5 = re.search('www.(w)+.com','www.bashrunning.com').group()
        ret6 = re.findall('www.(?:w+).com','www.bashrunning.com')
        print(ret1)             # 输出 ['g']
        print(ret2)             # 输出 [('b','g')]
        print(ret3)             # 输出 ['bashrunning']
        print(ret4)             # 输出 [('b','ashrunning')]
        print(ret5)             # 输出 www.bashrunning.com
        print(ret6)             # 输出 www.bashrunning.com    使用?:时,可以将分组的优先级降低;这样,就可以返回所有匹配的内容;
    

    2. search()

    返回一个对象(object);对象有group方法来取匹配结果;如果没有匹配到,则返回None;
    从左开始匹配,只返回匹配到的第一个对象;
    

    3. match()

    返回一个对象(object);只在字符串开头匹配,也是从左开始匹配,只匹配第一个对象;如果没有匹配到,则返回None;
    match方法可以看做特殊的search方法;即 re.match('a','abcd')  等效于  re.search('^a','abcd');
    

    4. split()

    分割字符串,返回一个列表;假如分隔符在字符串的边界,则返回的列表中会有一个空
    例如:
        import re
        ret1 = re.split('f','egefabc')
        print(ret1)          # 输出 ['ege','abc']
    
        ret2 = re.split('[fb]','egefabc')
        print(ret2)          # 输出 ['ege','a','c']
    
        ret3 = re.split('[ea]','egefabc')
        print(ret3)          # 输出 ['','g','f','bc']            
    

    5. sub()

    替换匹配的的字符为指定的字符;从左开始匹配,默认替换所有匹配到的;如果替换指定次数,加一个参数指定次数即可;
    例如:
        import re
        ret = re.sub('ba.*ing','baidu','www.bashrunning.com')
        print(ret)          # 输出 www.baidu.com   即,将 匹配到的替换为 指定的字符;中间的字符串(baidu)中的特殊字符也都是原生字符;
    
        ret2 = re.sub('abc','baidu','www.abc.com/www.abc.com',1)
        print(ret2)         # 输出 www.baidu.com/www.abc.com   指定了只替换一次;
    其实还有一个方法,subn(),可以返回替换的次数;
    例如:
        import re
        ret = re.subn('ba.*ing','baidu','www.bashrunning.com')
        print(ret)          # 输出 ('www.baidu.com',1)   
    

    6. compile()

    将指定的匹配规则编译为 一个正则表达式对象;类似定义了一个函数;
    例如:
        import re
        re_object = re.compile('bash')
        ret1 = re_object.findall('bashrunning.com')     # 匹配bash
        ret2 = re_object.findall('bash for linux')      # 匹配bash
    

    7. finditer()

    findall返回一个列表;finditer返回一个迭代器;
    例如:
        import re
    
        ret = re.finditer('d','wjz123wjk456')
        print(ret)          # 输出 <callable_iterator object at 0x000002491C4B24A8>
        g1=next(ret)        
        print(g1)           # 输出 <_sre.SRE_Match object; span=(3, 4), match='1'>
        print(g1.group())   # 输出 1
    

    三. 其他

    1. 分组

     例如:

    import re
    
    ret = re.search('(?P<name>.*)/(?P<date>.*)', 'wjz/20180201')
    print(ret.group())          # 返回 wjz/20180201
    print(ret.group('name'))    # 返回 wjz
    print(ret.groupdict())      # 返回 {'name': 'wjz', 'date': '20180201'}
    

    2. 贪婪匹配 和 惰性匹配

    正则中,元字符 * + ? 都是贪婪匹配。就是尽可能多的给你匹配处理;

    如果在元字符后面加上?,则会变为惰性匹配,即尽可能少的匹配;

    例如:

     import re
     ret1 = re.search('ab*','abbbbbb')
     print(ret1.group())                 # 返回 abbbbbb
     ret2 = re.search('ab*?','abbbbbb')
     print(ret2.group())                 # 返回 a
    

    3. search、match等返回的对象的方法

    获取对象:

    import re
    object = re.search('ab*','abbbbbb')     # 得到对象object
    

    接下来,我们看看这个对象object都有哪些方法。

    对象的数据描述符:

    • endpos

      返回object.group()的长度;汉字、数字、字母、特殊字符都算一个长度;

    • lastgroup

      返回最后组名;如果最后一组没有定义组名,则返回None;匹配规则使用()分组;

    • lastindex

      返回分组的个数;

    • pos

      再补充这个;

    • re

      返回对象匹配的规则;

    • regs

      返回一个元组;元组中分别是 object.group()第一个字符到最后一个字符的位置、第一组的位置、第二组的位置... 例如:

      import re
      
      ret = re.search('(?P<name>.*)/(?P<date>.*)/.*', 'wjz/20180201/4')
      print(ret.regs)             # 返回 ((0, 14), (0, 3), (4, 12))  注意,位置元组是顾头不顾尾;
      
    • string

      返回object配置时的原始字符串; 例如:

      import re
      
      ret = re.search('(?P<name>.*)/(?P<date>.*)/.{2}', 'wjz/20180201/44444')
      print(ret.group())          # 返回 wjz/20180201/44
      print(ret.string)           # 返回 wjz/20180201/44444
      

    对象的类方法:

    • group(...)

      返回匹配到的所有字符; 例如:

          import re
          ret = re.search('(?P.{3})/(?P.*)/.{3}', 'kkkkwjz/20180201/44444')
          print(ret.group())		# 返回 wjz/20180201/444
      
    • groupdict(self, /, default=None)

      返回一个字典;字典的key为组名;键值是改组匹配到的字符; 例如:

          import re
          ret = re.search('(?P.{3})/(?P.*)/.{3}', 'kkkkwjz/20180201/44444')
          print(ret.groupdict())		# 返回 {'name': 'wjz', 'date': '20180201'} 
      
    • groups(self, /, default=None)

      以元组形式返回分组匹配到的内容; 例如:

          import re
          ret = re.search('(?P.{3})/(?P.*)/.{3}', 'kkkkwjz/20180201/44444')
          print(ret.groups())			# 返回 ('wjz', '20180201') 即分组匹配到的字符
      
    • span(self, group=0, /)

      返回一个元组,匹配到的字符串的在原始字符串中的起始结束位置;位置从0开始,顾首不顾尾; 例如:

          import re
      
          ret = re.search('(?P.{3})/(?P.*)/.{3}', 'kkkkwjz/20180201/44444')
          print(ret.group())			# 返回 wjz/20180201/444
          print(ret.span()			# 返回 (4,20)   即 w为'kkkkwjz/20180201/44444'的第四个位置,第三个4位于第19个位置;
      
    • start(self, group=0, /)

      返回一个数字,该数字是匹配到的字符串的最后一个字符在原字符串的位置;这里的end起始是span方法中的start位置; 例如:

          import re
          ret = re.search('(?P.{3})/(?P.*)/.{3}', 'kkkkwjz/20180201/44444')
          print(ret.group())		# 返回 wjz/20180201/444
          print(ret.span())		# 返回 (4,20)
          print(ret.start())		# 返回数字 4		即w在'kkkkwjz/20180201/44444'是第4个位置处;
      
    • end(self, group=0, /)

      返回一个数字,该数字是匹配到的字符串的最后一个字符在原字符串的位置+1;这里的end起始是span方法中的end位置; 例如:

      	
          import re
          ret = re.search('(?P.{3})/(?P.*)/.{3}', 'kkkkwjz/20180201/44444')
          print(ret.group())		# 返回 wjz/20180201/444
          print(ret.span())		# 返回 (4,20)
          print(ret.end())		# 返回数字 20		即第三个4 在'kkkkwjz/20180201/44444'是第19个位置处;
      
    • expand(self, /, template)

      这个可以用sub方法替代;字符替换的;具体用法再补充;

    四. 正则修饰符

    正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:

    修饰符描述
    re.I(注:大写的i) 使匹配对大小写不敏感
    re.L 做本地化识别(locale-aware)匹配
    re.M 多行匹配,影响 ^ 和 $
    re.S 使 . 匹配包括换行在内的所有字符
    re.U 根据Unicode字符集解析字符。这个标志影响 w, W, , B.
    re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。

    案例

    • re.I

      pattern='aB'
      print(bool(re.match(pattern,'ab',flags=re.I)))#结果为True,若不加re.I则为False
    • re.M

      re.M 即 re.MULTILINE 影响'^'和'$'的行为,指定了以后,'^'会增加匹配每行的开始(也就是换行符后的位置); '$'会增加匹配每行的结束(也就是换行符前的位置)。

      pattern='^a{2}bb$'
      print(bool(re.match(pattern,'aabb
      aabb',re.M)))       #加上re.M结果为True,否则为False
    • re.S

      pattern='w+|.'
      print(bool(re.match(pattern,'
      ghhgb',re.S)))        #加上re.S为True,否则为False
    如需转载,请注明出处,否则本人会追究法律责任!
  • 相关阅读:
    使用tornado的gen模块改善程序性能
    分析Linux内核中进程的调度(时间片轮转)-《Linux内核分析》Week2作业
    博客园配置MarsEdit客户端
    分析一个C语言程序生成的汇编代码-《Linux内核分析》Week1作业
    微信支付的开发流程
    探究加法操作的原子性
    mac下mysql数据库的配置
    从range和xrange的性能对比到yield关键字(中)
    使用装饰器时带括号与不带括号的区别
    从range和xrange的性能对比到yield关键字(上)
  • 原文地址:https://www.cnblogs.com/hacker001/p/10092365.html
Copyright © 2011-2022 走看看