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

    正则表达式

    一.认识正则表达式

      正则表达式是什么 ?

        正则表达式是一门单独的语音,不仅属python,很多语言都可以调用它,它自成体系

      正则表达式有什么用呢?

        首先我们看一下python自带的字符串的一些功能方法

    str1 = "abcdefg"
    result1 = str1.find("b")
    result2 = str1.find("bc")
    result3 = str1.split("b")
    result4 = str1.replace("ab", "AB")
    print("b的位置是:%s" % result1)
    print("bc的位置是:%s" % result2)
    print("字符串以b分割成:%s" % result3)
    print("字符串替换后的结果是:%s" % result4)
    

      我们可以观察得到,无论是查找,分割,或者替换都需要明确具体的元素

      而正则表达式可以给出一个pattern,符合要求的可以有很多,不仅仅局限唯一

     

    二.正则表达式的元字符及其意义

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

      ^:行首锚定

      $:行尾锚定

      *:匹配任意次,贪婪匹配 等价于{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()

    import re
    
    # re.match()  从头匹配,返回一个对象
    # 无分组匹配
    origin = "hello alex bcd alex lge alex acd 19"
    r = re.match("hw+", origin)
    print(r.group())  # 获取匹配到的所有结果(无分组时,只有group有意义)
    print(r.groups())  # 获取模型中匹配到的分组结果,无意义
    print(r.groupdict())  # 获取模型中匹配到的分组中所有执行了key的组
    
    '''
    hello
    ()
    {}
    '''
    
    # 有分组匹配
    r = re.match("(h)(w+)", origin)
    print(r.group())      # 获取匹配到的所有结果
    print(r.groups())     # 获取模型中匹配到的分组结果,分组才有意义
    r = re.match("(?P<n1>h)(?P<n2>w+)", origin)
    print(r.groupdict())  # 获取模型中匹配到的分组中所有执行了key的组,分组才有意义
    
    '''
    hello
    ('h', 'ello')
    {'n1': 'h', 'n2': 'ello'}
    '''
    

     

    2.re.search()

    import re
    #re.search() 浏览全部字符串,匹配第一个合法的字符串,返回一个对象
    #无分组匹配
    origin = "hello alex bcd alex lge alex acd 19"
    r = re.search("aw+", origin)
    print(r.group())     #获取匹配到的所有结果(无分组时,只有group有意义)
    print(r.groups())    #获取模型中匹配到的分组结果,无意义
    print(r.groupdict()) #获取模型中匹配到的分组中所有执行了key的组
    '''
    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()

    import re
    origin = "a2b3c4d5"
    result = re.findall("d+wd+", origin)
    print(result)
    '''
    ['2b3', '4d5']
    '''
    #无分组
    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)
    '''
    ['lex', 'lex', 'lex', '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_-]+)+

      

    七.课后作业,计算器开发

    
    re.split("([^()]+)", expression)    ()有特殊意义,表示分组,[]里面的符号都没有特殊意义,不需要转义
    		
    def f1(ex):
      pass
    origin = "1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) " while True: result = re.split("(([^()]+))",origin,1) if len(result) == 3: #before = result[0] #content = result[1] #after = result[2]
    before,content,after = result r = f1(content) new_str = before + r + after origin = new_str else: final = f1(result[0]) print(final) print(origin) break

    计算1*2+3*4+5*6+..+99*100的值

    # 1*2+3*4+5*6+7*8+9*10
    
    import re
    
    
    def f1(arg):
        arg1, arg2 = arg.split('*')
        r = (int(arg1)) * (int(arg2))
        return str(r)
    
    
    def seq(arg1, arg2):
        seq = ''
        for i in range(arg1, arg2):
            if i % 2 == 0 and i != arg2 - 1:
                seq = seq + str(i) + '+'
            elif i % 2 != 0:
                seq = seq + str(i) + '*'
            else:
                seq = seq + str(i)
    
        return seq
    
    
    def add1(data):
        summ = 0
        ret = data.split('+')
        for i in ret:
            summ = int(i) + summ
    
        return summ
    
    
    if __name__ == '__main__':
        a = int(input("输入一下格式:1*2+3*4+5*6+7*8+9*10,首:"))
        b = int(input("输入一下格式:1*2+3*4+5*6+7*8+9*10,尾:"))
        seq1 = seq(a, b + 1)
        while True:
            result = re.split(r'(d{1,2}*d{1,2})', seq1, 1)
            if len(result) == 3:
                # print(result)
                before = result[0]
                content = result[1]
                after = result[2]
                r = f1(content)
                new_str = before + r + after
                seq1 = new_str
            else:
                # print(result)
                # print(seq1)
                break
        result = add1(seq1)
        print(result)
    
  • 相关阅读:
    [Head First Python]2. BIF(内置函数)
    [转]mac下Python升级到指定的版本
    [Head First Python]2. python of comment
    自动化测试-----Python基础
    自动化测试----python等工具下载、测试环境搭配、常用的DOS命令
    Python初识与安装
    Python网络爬虫部分
    不知道数据库中表的列类型的前提下,使用JDBC正确的取出数据
    如何做好测试接口
    测试登录界面
  • 原文地址:https://www.cnblogs.com/wuwen19940508/p/6876246.html
Copyright © 2011-2022 走看看