python常用模块——re

Posted 黑客&海盗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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方法替代;字符替换的;具体用法再补充;

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

python常用模块之re模块(正则)

常用python日期日志获取内容循环的代码片段

python全栈开发第九篇Python常用模块一(主要是re正则和collections)

python正则--re模块常用方法

python常用模块之——正则re模块

常用模块之re模块以及正则表达式扩展