zoukankan      html  css  js  c++  java
  • Python之正则表达式

    一、正则表达式的元字符及其意义

           . :匹配任意除换行符的单个字符

      ^:行首锚定

      $:行尾锚定

      *:匹配任意次,贪婪匹配 等价于{0,}

      +:匹配1到多次,贪婪匹配 降价与{1,}

      ?:匹配0或1次,贪婪匹配 降价与{0,1}

      {}:固定次数

        {3}:3次

        {3,5}:3到5次

      :

        1.反斜杠后边跟元字符去掉特殊功能

        2.反斜杠后边跟普通字符实现特殊功能

          d:匹配任何单个十进制数,它相当于类[0-9],匹配一个数字

          D:匹配任何单个非数字字符,它相当于[^0-9]

          s:匹配任何单个空白字符,它相当于类[ fv]

          S:匹配任何单个非空白字符,它相当于[^ fv]

          w:匹配任何单个字母数字字符;它相当于类[a-zA-Z0-9]

          W:匹配任何单个非字母数字字符,它相当于类[^a-zA-Z0-9]

          :匹配一个单词边界,也就是指单词和空格间的位置 

        3.引用序号对应的字组所匹配的字符串

    re.search(r"(alex)(eric)com2", "alexericcomeric").group()
     
     'alexericcomeric'    

      []:字符集中没有失去意义的元字符 “ - ”,“ ^ ”,“ ”

        ^:字符集中的^表示非

    re.findall('[^1-9]','a1b2c3')
     
    ['a', 'b', 'c']

        :转义的普通字符d,w,s等用法不变

    re.findall('[d]','ww3 wa8.d0')
     
    ['1', '2', '3']

        ():分组,将一串字符做为一个整体

          贪婪模式

    re.search(r"a(d+)","a12345678b").group()
    a12345678  

          非贪婪模式

    re.serach(r"a(d+?)","a12345678b").group()
    a1

    二.贪婪模式的存在机制

    re.findall(r"a(d+?)", "a23b") #非贪婪模式
    ['2']  #匹配括号里面的
    
    
    
    re.findall(r"a(d+)b", "a23b") #如果前后均有限定条件,则不按非贪婪模式匹配
    ['23']
     
    re.findall(r"a(d+?)b", "a23b") #如果前后均有限定条件,则不按非贪婪模式匹配
    ['23'
    
    
    re.findall(r"a(d+)", "a23b")  #贪婪模式
    ['23']

    三.rawstring原生字符串

      正则机制:在正则表达式中,python编译器先拿到pattern里面的内容,编译后再传给正则表达式从而匹配到

           符合要求的字符串

    例1

    import re
     
    result = re.findall("\\", 'abccom')
    '''
    为了匹配到,又因为为正则元字符,python中也有特殊意义
    python编译器拿到4个先转义成2个\,交给正则的编译器
    2个再转义成一个无意义的字符\,即可匹配到
    '''
    print(result)
    '''
    匹配结果为['\']
    这是python对元字符匹配后的显示方法
    '''
     
    result1 = re.findall(r"\", 'abccom')
    '''
    引入原生字符串,直接将2个交给正则表达式去解析
    '''
    print(result1)

    例2

    import re
     
    result1 = re.findall("d", 'a1b2c3')
    print(result1)
    '''
    ['1', '2', '3']
    本身需要转义的d,却依然成功匹配的原因是:
    python中没有d这个转义字符,没有产生冲突
    '''
     
    result2 = re.findall("\d", 'a1b2c3')
    '''
    那么加上\也不影响结果
    '''
    print(result2)
     
    result3 = re.findall(r"d", 'a1b2c3')
    '''
    加入原生字符串的效果依然是一样
    '''
    print(result3)

    例3

    import re
     
    result1 = re.match('blow', 'blow')
    '''
    python中为删除符,有特殊意思,所以直接如上写法无法得到匹配结果
    '''
    print(result1) #None
     
    result2 = re.match('\bblow', 'blow')
    '''
    给加上转义符,由python转换成
    再由正则解释成自己的独特的意义
    '''
    print(result2.group()) #blow
     
    result3 = re.match(r'blow', 'blow')  #同理,引入原生字符之后
    print(result2.group())

    四、正则表达式是的基本方法

    1、re.match()    从头匹配

    #1、无分组
    origin = "hello alex bcd alex lge alex acd 19"
    r = re.match("hw+", origin)
    print(r.group())  # 获取匹配到的所有结果
    print(r.groups())  # 获取模型中匹配到的分组结果
    print(r.groupdict())  # 获取模型中匹配到的分组结果
    #输出结果:hello  ()  {}
    #2、有分组
    # 为何要有分组?提取匹配成功的指定内容(先匹配成功全部正则,再匹配成功的局部内容提取出来)
    origin = "hello alex bcd alex lge alex acd 19"
    r = re.match("(h)(w+)",origin)
    r = re.match("(?P<n1>h)(?P<n2>w+)",origin)
    print(r.group())  # 获取匹配到的所有结果,
    print(r.groups())  # 获取模型中匹配到的分组结果,在要取的内容加上"()"就可以取出来
    print(r.groupdict())  # 获取模型中匹配到的分组结果,在要取的内容前面加上"?P<>"
    #输出结果:hello   ('h', 'ello')   {}

    2、re.search()      浏览全部字符串,匹配第一个符合规则的字符串

    origin = "hello alex bcd alex lge alex acd 19"
    # 无分组
    r = re.search("aw+", origin)
    print(r.group())  # 获取匹配到的所有结果
    print(r.groups())  # 获取模型中匹配到的分组结果
    print(r.groupdict())  # 获取模型中匹配到的分组结果
    #输出结果:alex  ()   {}
    # 有分组
    r = re.search("a(w+).*(?P<name>d)$", origin)
    print(r.group())     # 获取匹配到的所有结果
    print(r.groups())    # 获取模型中匹配到的分组结果
    print(r.groupdict()) # 获取模型中匹配到的分组中所有执行了key的组
    #输出结果:   alex bcd alex lge alex acd 19
    #                   ('lex', '9')
    #                  {'name': '9'}             
    3.re.findall()   将匹配到的所有内容都放置在一个列表中
    
    
    #1、
    n = re.findall("d+wd+","a2b3c4d5")
    print(n)
    #结果:['2b3', '4d5']
    #匹配成功后,不会在依次向后,跳过匹配到的,然后继续向后匹配
    #2、
    n = re.findall("","a2b3c4d5")
    print(n)
    #结果:['', '', '', '', '', '', '', '', '']
    #在匹配到空的东西也会占位置
    #无分组
    origin = "hello alex bcd alex lge alex acd 19"
    r = re.findall("aw+", origin)
    print(r)
    '''
    ['alex', 'alex', 'alex', 'acd']
    '''
     
    #有分组
    origin = "hello alex bcd alex lge alex acd 19"
    #优先捕获
    r = re.findall("a(w+)", origin)
    print(r)
    '''
    ['lex', 'lex', 'lex', 'cd']
    '''
    r = re.findall("(a)(w+)", origin)
    print(r)
    '''
    [('a', 'lex'), ('a', 'lex'), ('a', 'lex'), ('a', 'cd')]
    '''
    #去除优先捕获加 ?:
    r = re.findall("a(?:w+)", origin)
    print(r)
    '''
    ['alex', 'alex', 'alex', 'acd']
    '''
    #内嵌分组:从左到右,从外到里,有几个括号取几次
    r = re.findall("(a)(w+(e))(x)", origin)
    print(r)
    '''
    [('a', 'le', 'e', 'x'), ('a', 'le', 'e', 'x'), ('a', 'le', 'e', 'x')]
    '''

    4.re.finditer()

    import re
    #finditer每次迭代的时候,内容才会创建
    origin = "hello alex bcd alex lge alex acd 19"
    r = re.finditer("(a)(w+(e))(x)", origin)
    print(r)
    for i in r:
        print(i, i.group(), i.groups(), i.groupdict())
    '''
    <callable_iterator object at 0x020F90F0>
    <_sre.SRE_Match object; span=(6, 10), match='alex'> alex ('a', 'le', 'e', 'x') {}
    <_sre.SRE_Match object; span=(15, 19), match='alex'> alex ('a', 'le', 'e', 'x') {}
    <_sre.SRE_Match object; span=(24, 28), match='alex'> alex ('a', 'le', 'e', 'x') {}
    '''    

    5.re.split() 可指定分割次数

    import re
    #re.split 可指定分割次数
    origin = "hello alex bcd abcd lge acd 19"
     
    #无分组 不包含做为分割的那个字符串
    n = re.split("aw+", origin)
    print(n)
    '''
    ['hello ', ' bcd ', ' lge ', ' 19']
    '''
     
    #有分组 显示分组里的内容
    n = re.split("(aw+)",origin)
    print(n)
    '''
    ['hello ', 'alex', ' bcd ', 'abcd', ' lge ', 'acd', ' 19']
    '''
    
    
    #分割流程:split
    #p = re.compile(r"d+")
    #p.split('one1two2three3four4')
    #['one', 'two', 'three', 'four', '']
    #首先找到1,分成one,two2three3four4
    #然后找到2,分成two,three3four4
    #然后找到3,分称three,four4
    #最后找到4,分成four,和 空

    6.re.sub()与re.subn()

    import re
    #正则中替换用sub  ,subn(将替换后字符串和替换次数放在一个元组里面)
    #re.sub(pattern, repl, string, max=0)  max为替换次数
    re.sub("g.t", "have", "i get A, i got B, I gut C",max = 2)
    #"i have A, i have B, I gut C"
    new,count = re.subn("g.t", "have", "i get A, i got B, I gut C")
    print(new,count)
    #("i have A, i have B, I have C",3)

    7.总结

    #search与match一旦匹配成功,就是返回一个对象,对象的常用方法如下
    import re
     
    a = '123abc456'
    r1 = re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(0)  # 123abc456
    r2 = re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(1)  # 123
    r3 = re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(2)  # abc
    r4 = re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(3)  # 456
    #start() 返回匹配开始的位置
    #end() 返回匹配结束的位置
    #span() 返回一个元组,包含匹配(开始,结束)的位置

    五.常见的正则表达式 

    IP:
    ^(25[0-5]|2[0-4]d|[0-1]?d?d)(.(25[0-5]|2[0-4]d|[0-1]?d?d)){3}$
    手机号:
    ^1[3|4|5|8][0-9]d{8}$
    邮箱:
    [a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+
  • 相关阅读:
    小埋的Dancing Line之旅:比赛题解&热身题题解
    洛谷P1311 选择客栈
    洛谷 P1039 侦探推理
    洛谷P1140 相似基因
    反⑨baka拖更大队:临时约法
    随机数据生成器
    洛谷P2285 【[HNOI2004]打鼹鼠】
    洛谷P3958 奶酪
    YII 关联查询
    Filter
  • 原文地址:https://www.cnblogs.com/Acekr/p/7426236.html
Copyright © 2011-2022 走看看