• python正则表达式


    元字符:匹配字符、匹配位置、匹配数量、匹配模式.

              常见元字符列表

                    .       匹配除换行符以外的任意字符

                     匹配单词的开始或结束

                   d  匹配数字

                    w 匹配字母、数字、下划线或汉字

                    s 匹配任意空白符,包括空格、制表符(Tab)、换行符、中文全角空格等

                     ^ 匹配字符串的开始

                     $匹配字符串的结束

               常用限定符

              *   重复零次或更多次

              +  重复一次或更多次

              ? 重复零次或一次

             {n}重复n次

             {n,}重复n次或更多次

             {n,m}重复n到m次

             常用反义字符

              W     匹配任意不是字母、数字、下划线的字符

               S    匹配任意不是空白符的字符

               D 匹配任意非数字的字符

                B 匹配不是单词开头或结束的位置

               [^a] 匹配除了a以外的任意字符

              [^abcde] 匹配除了a、b、c、d、e这几个字母以外的任意字符

               [^(123|abc)] 匹配除了1、2、3或者a、b、c这几个字符以外的任意字符

        后向引用:

                  使用小括号指定一个表达式就可以看做是一个分组。默认情况下,每个分组会自动拥有一个组号,规则是:从左至右,以分组的左括号为标志,第一个出现的分组组号为1

                      表 常用的分组形势

              分类                 语法                                            含义

                                      (exp)                 匹配exp,并捕获文本到自动命名的组里

                捕获               (?P<name>exp) 捕获exp,并捕获wenben到名称为name的组里

                                       (?:exp)     匹配exp,不捕获匹配的文本,也不给此分组分配组号

                                       (?=exp)   匹配exp前面的位置

              零宽断言           (?<=exp)  匹配exp后面的位置

                                       (?!exp) 匹配后面跟的不是exp的位置

                                       (?<!exp)匹配前面不是exp的位置

                   注释              (?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,只用于提供注释让人阅读

    零宽度断言:'','^'匹配的是一个位置,而且这个位置需要满足一定的条件,我们把这个条件称为断言或者零宽度断言。

               零宽度正预测先行断言:(?=exp),他断言位置的后面能匹配表达式exp.比如[a-z]*(?=exp)匹配以ing结尾的部分,查找I love cooking and singing时会匹配出cook和sing.

    先行断言的执行步骤是从要匹配字符的最右端找到第一个“ing” ,再匹配前面的表达式,如无法匹配则查找第二个。

             零宽度正回顾后发断言:(?<=exp),他断言此位置的前面能匹配表达式exp。比如(?<=abc).*匹配以abc开头的字符串的后面部分,可以匹配abcdefgabc中defgabc二不是abcdefg,后发断言和先行断言正好相反,他从要匹配的字符串的最左端开始查找断言表达式,之后再匹配后面的字符串,如果无法匹配则继续查找第二个断言表达式,如此反复。

             零宽度负预测先行断言:(?!exp) 断言此位置的后面不能匹配表达式exp。比如((?!abc)w)+匹配不包含连续字符串abc的单词

             零宽度负预测后发断言:(?<!exp)断言此位置的前面不能匹配表达式exp.比如(?<![a-z])d{7}匹配前面不是小写字母的七位数字。

    用于匹配不包含属性的简单HTML标记内的内容  (?<=<(w+)>).*(?=</1).

       贪婪与懒惰

                  当正则表达式中包含能接受重复的限定符时,通常的行为是(整个表达式能匹配的前提下)匹配尽可能多的字符,

    这就是贪婪模式。以表达式aw+b为例,如果搜所a12b34b尽可能多的匹配,左后就会匹配整个a12b34b而不是a12b,

    但如果想匹配出a12b,该如何处理呢?就要开启懒惰模式将上面aw+b改为aw+?b就可以啦

                                     懒惰限定符的使用方式

                   *?  重复任意多次,但尽可能少重复

                    +? 重复1次或更多次,但尽可能少重复

                    ??重复0次或1次,但尽可能少重复

                    {n,m}?重复n到m次,但尽可能少重复

                    {n,}?重复n次以上,但尽可能少重复

                                  表python的匹配规则

    语法                          含义                      表达式            完整匹配字符串

    A                           仅匹配字符串开头    Aabc                 abc

                                仅匹配字符串末尾     abc               abc

    (?P<name>)            分组,除了原有编号外在指定一个额外的别名    (?P<word>abc){2}  abcabc

    (?P=name)                引用别名为<name>的分组匹配到的字符串     (?P<id>d)abc(?P=id)    1abc1,5abc5

    python中的匹配处理方法,主要是通过re模块里面的几个方法

    1.re.match(pattern,string[,float])

    此函数是从输入参数string头位置开始匹配,尝试匹配pattern,一直向后匹配,如果遇到无法匹配或者匹配到最后位置,立即返回None,反之获取匹配的结果

    案例,通过运行结果可以知道,此种方法是固定位置的匹配,就是字符串必须从最开始的位置匹配。

    import re
    
    pattern = re.compile(r'(?:d+)')
    
    matchresult1 = re.match(pattern, 'abc123cd345')
    
    matchresult2 = re.match(pattern, '123abc4567')
    
    if not matchresult1:
        print('matchresult1 no proper regular the result is None')
    else:
        print(matchresult1.groups())
    
    if not matchresult2:
        print('matchresult2 no proper regular the result is None')
    else:
        #group()在分组和未分组的情况下都会返回数据
        #groups()只会返回分组情况下,每一组里的值。
        print(matchresult2.group())
    View Code

     2.re.search(pattern,string[,flags])

    此函数与match方法非常相似,区别在于match()函数只在string的开始位置匹配,search()会扫描整个string查找匹配,

    match()只有在起始位置匹配成功后才返回,如果不是比开始位置成功的话,直接返回None

    案例 只输出123表名,满足条件立即返回,不会进一步继续寻找其他满足条件的匹配

    #将正则表达式编译成pattern对象
    pattern2=re.compile(r'd+')
    #匹配文本
    result1=re.search(pattern2,'abc123eff3456dd')
    
    if result1:
        print(result1.group())
    else:
        print('匹配失败哦!')

     3.re.split(pattern,string[,maxsplit])

    此函数按照能匹配的子串将string分割后返回列表。maxsplit用于指定最大分割次数,不指定,则将全部分割。

    案例输出['abc', 'eff', 'dd']

     将正则表达式编译成pattern对象
    pattern2 = re.compile(r'd+')
    print(re.split(pattern2, 'abc123eff3456dd'))

    4.re.findall(pattern,string[,flags])

    搜索整个string,以列表形式返回能匹配的全部子串

    案例输出结果   ['123', '3456']

    # 将正则表达式编译成pattern对象
    pattern2 = re.compile(r'd+')
    print(re.findall(pattern2, 'abc123eff3456dd'))
    View Code

     5.re.finditer(pattern,string[,flags])

    搜索整个string以迭代器的形式返回能匹配的全部Match对象

    # 将正则表达式编译成pattern对象
    pattern2 = re.compile(r'd+')
    matchiter = re.finditer(pattern2, 'abc123eff3456dd')
    for match in matchiter:
        print(match.group())
    View Code

    6.re.sub(pattern,repl,string[,count])

     使用repl替换string中每一个匹配的子串后返回替换后的字符串。当repl是一个字符串时,可以使用id或g<id>、

    g<name>引用分组,但不能使用编号0,当repl是一个方法时,这个方法应当只接受一个参数(Match对象),并返回

    一个字符串用于替换(返回的字符串不能引用分组)。count用于指定最多替换的次数,不指定时全部替换

    案例如下

    import re
    
    p5 = re.compile(r'(?P<world1>w+) (?P<world2>w+)')  # 使用名称
    s = 'i say, hello world!'
    print(p5.sub(r'g<world2> g<world1>', s))
    print('--------------------')
    print(p5.sub(r'2 1', s))
    print('--------------------')
    
    
    def func(m):
        return m.group(2).title() + ' ' + m.group(1).title()
    
    
    print(p5.sub(func, s))

     7.re.subn(pattern,repl,string[,count])

    返回(sub(repl,string[,count]),替换次数).

    Match对象的属性

                 string:匹配时使用的文本

                  re:匹配时使用的Pattern对象

                   pos:文本中正则表达式开始搜索的索引。

                  endpos:文本中正则表达式结束搜索的索引。

                   lastindex:最后一个被捕获的分组在文本中的索引。如果没有被捕获的分组,将为None

                   lastgroup:最后一个被捕获的分组的别名。如果这个分组没有别名或者没有被捕获的分组,将为None

    Match 对象的方法

           group([group1,...]):获得一个或多个分组截获的字符串,指定多个参数时将以元组形式返回。group1可以使用

    编号也可以使用别名,编号0代表整个匹配的子串,不填写参数是,返回group(0)。没有截获字符串的组返回None

    截获多次的组返回最后一次截获的子串。

           groups([default]):以元组形式返回全部分组截获的字符串。相当于调用group(1,2,3...last).default表示没有截获字符串的组以这个值代替

    默认为None

           groupdict([default]):返回以有别名的组的别名为键,以该组截获的子串为值得字典,没有别名的组不包含在内。default含义同上

              start([group]):返回指定的组截获的子串在string中的起始索引(子串第一个字符的索引)。group默认值为0

               end([group]):返回指定的组截获的子串在string中的结束索引(子串最后一个字符的索引+1).group默认值为0

             span([group]):返回(start(group),end(group))。

              expand(template):将匹配到的分组代入template中然后返回。template中可以使用id或g<id>、g<name>引用分组,

    但不能使用编号0.  id与g<id>是等价的。

    案例

    print('match的用法!')
    pattern = re.compile(r'(w+) (w+) (?P<word>.*)')
    match = pattern.match('I love you!')
    print('match.string:', match.string)
    print('match.re:', match.re)
    print('match.pos:', match.pos)
    print('match.endpos:', match.endpos)
    print('match.lastindex:', match.lastindex)
    print('match.lastgroup:', match.lastgroup)
    print('match.group(1,2):', match.group(1, 2))
    print('match.groups():', match.groups())
    print('macth.groupdict():', match.groupdict())
    print('match.start(2):', match.start(2))
    print('match.end(2):', match.end(2))
    print('match.span(2):', match.span(2))
    print(r'match.expand(r"2 1 3"):', match.expand(r'2 1 3'))
    View Code

           

          

          

                

                  

                  

                 

             

              

               

                    

                    

         

  • 相关阅读:
    面向对象
    PIL库学习及运用
    Jieba库使用和好玩的词云
    Python汉诺塔问题
    用python计算圆周率PI
    使用python画一只佩奇
    面向对象与正则表达式的学习
    美白,磨皮,搞笑图片处理
    tuetle制作汉诺塔
    python圆周率的计算及进度条提示
  • 原文地址:https://www.cnblogs.com/09120912zhang/p/7623433.html
Copyright © 2020-2023  润新知