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

    一.简介

      正则表达式(或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现,再被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行

    二.常用字符

      1.字符匹配

      • 元字符
    . 代指除了换行符以外的任何字符,只能匹配一个字符
    ^ 匹配行首
    $ 匹配行尾
    * 重复匹配0~多次,贪婪匹配
    + 重复匹配1~多次,至少要匹配一次
    ? 匹配0次或者一次,可有可无,最多只能有一个
    {} 精确定匹配次数,或者范围
    [] 常用来制定一个字符集,如[ab]匹配 a 或b;其他的元字符在[]中不起作用,除了【-】【^】
    |
    () 分组第一个组号为1
    转译

    反斜杠:

    反斜杠后边跟元字符去除特殊功能
    反斜杠后边跟普通字符实现特殊功能
    引用序号对应的字组所匹配的字符串

    如:

    #匹配'c'和'e'中间的任何字符
    >>> re.findall('c.e','abcdef')
    ['cde']
    #匹配'c'和’f'之间的任两个字符
    >>> re.findall('c..f','abcdef')
    ['cdef']
    #匹配在字符串'ef'之前的一个字符
    >>> re.findall('.ef','abcdef')
    ['def']
    #以'a'开头的字符
    >>> re.findall('^a','abacd')
    ['a']
    #以'st'结尾
    >>> re.findall('st$','test')
    ['st']
    >>> re.findall('^ac$','abc')
    []
    #以'a'开头‘c'结尾的字符
    >>> re.findall('^ac$','ac')
    ['ac']
        • 特殊字符

     

    d 匹配任何十进制数;它相当于类 [0-9]
    D 匹配任何非数字字符;它相当于类 [^0-9]
    s 匹配任何空白字符;它相当于类  [ fv]
    S 匹配任何非空白字符;它相当于类 [^ fv]
    w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]
    W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]
     匹配一个单词边界,也就是指单词和空格间的位置
    import re
    #匹配获取话号码
    p = re.compile(r'd{3}-d{6}')
    print(p.findall('010-628888'))
    #匹配获取网址
    www = "www.baidu.com"
    print(re.findall(r'w+.w+.com',www))
    #取浮点数
    print(re.findall(r'd+(.d*)?','num 10.02'))

     

    三.re内置函数

    1. match()

    作用  

    决定 RE 是否在字符串刚开始的位置匹配

    用法 :

    re.match(pattern, string, flags=0)

    pattern: 编译时用的表达式字符串。

    flags    参数flags用于编译pattern时指定匹配模式,如:是否区分大小写,多行匹配等等。

    注意:这个方法并不是完全匹配。当pattern结束时若string还有剩余字符,仍然视为成功。想要完全匹配,可以在表达式末尾加上边界匹配符'$'

    >>> re.match('com', 'comwww.runcomoob').group()
    'com'
    #match是以什么开始匹配,加$以什么结果可以达到完全匹配的目的
    
    >>> re.match('com$', 'comwww.runcomoob').group()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'NoneType' object has no attribute 'group'

    2. search() 

      作用:  

      扫描字符串,找到这个 RE 匹配的位置

    参数:

    re.search(pattern, string, flags=0)

    一旦匹配成功,就是一个match object 对象,而match object 对象拥有以下方法:
    group()    返回被 RE 匹配的字符串
    start()    返回匹配开始的位置
    end()    返回匹配结束的位置
    span()    返回一个元组包含匹配 (开始,结束) 的位置
    group() 返回re整体匹配的字符串,可以一次输入多个组号,对应组号匹配的字符串。

    groups()返回一个包含正则表达式中所有小组字符串的元组,从 1 到 所含的小组号,通常groups()不需要参数,返回一个元组,元组中的元就是正则
    表达式中定义的组。

    >>> re.search('^a','abcd').group()
    'a'
    >>> a = "123abc456"
    >>> re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)
    '123abc456'
    >>> re.search(r"(alex)(eric)com2","alexericcomeric").group()
    'alexericcomeric'
    import re
    a = "123abc456"
    re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)
    re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1)
    re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2)
    re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3)

    3.findall()

      作用:

      找到 RE 匹配的所有子串,并把它们作为一个列表返回

       参数:

      re.findall(pattern, string, flags=0)

    >>> p = re.compile(r'd+')
    >>> p.findall('one1two2three3four4')
    ['1', '2', '3', '4']

      4.finditer()

      作用:

      搜索string,返回一个顺序访问每一个匹配结果(Match对象)的迭代器

      找到 RE 匹配的所有子串,并把它们作为一个迭代器返回

      参数:

      re.finditer(pattern, string, flags=0)

      

    import re
    p = re.compile(r'd+')
    iterator = p.finditer('12 drumm44ers drumming, 11 ... 10 ...')
    for match in iterator:
        print(match.group(), match.span())

      5.split()  作用:

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

    参数:

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

     

    >>> p = re.compile(r'd+')
    >>> p.split('one1two2three3four4')
    ['one', 'two', 'three', 'four', '']
    >>> re.split('[a-z]','1a2b3c4d')
    ['1', '2', '3', '4', '']

    6.sub()

    作用:

    使用re替换string中每一个匹配的子串后返回替换后的字符串

    用法 :

     

    re.sub(pattern, repl, string, count=0, flags=0)

     

    >>> re.sub('[1-2]','A','123456abcdef')
    'AA3456abcdef' 
    import re
    #替换全文空格为[]
    p = re.compile(r's')
    text = 'test dkjf dkfj'
    print(p.sub(r'',text))
    def func(m):
        return m.group(0) + '[' + ']' + m.group(0)
    print(p.sub(func,text))

    7.subn()

    作用:

    返回替换次数

    用法 :

    subn(pattern, repl, string, count=0, flags=0)

     

    >>> re.subn('[1-2]','A','123456abcdef')
    ('AA3456abcdef', 2)

     

      8.compile()

    作用:

      编译正则表达式模式,返回一个对象的模式
    用法 :

    re.compile(pattern, flags=0)

     

    p = re.compile(r'd+')
    iterator = p.finditer('12 drumm44ers drumming, 11 ... 10 ...')
    for match in iterator:
     match.group() , match.span()

     

    • re.I    使匹配对大小写不敏感

    • re.L    做本地化识别(locale-aware)匹配

    • re.M    多行匹配,影响 ^ 和 $

    • re.S    使 . 匹配包括换行在内的所有字符

     练习:

    思路:

    1.提取最里层括号内的公式

    2.先计算最里层公式内的*/将结果替换到原公式

    3.再次循环执行前两步得到结果

    计算器

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import re
    
    def final(formula):
        formula = formula.replace('++','+').replace('+-','-').replace('-+','-').replace('--','+')
        num = re.findall('[+-]?d+.?d*',formula)
        total = 0
        for i in num:
            total += float(i)
        return total
    
    
    def mul_div(formula):
        while True:
            ret = re.split('(d+.?d*[*/][-]?d+.?d*)',formula,1)
            if len(ret) == 3:
                ber, cent, aft = ret
                if '*' in cent:
                    new_cent = re.split('*',cent)
                    sub_res = float(new_cent[0]) * float(new_cent[1])
                    formula = ber + str(sub_res) + aft
                elif '/' in cent:
                    new_cent = re.split('/', cent)
                    sub_res = float(new_cent[0]) / float(new_cent[1])
                    formula = ber + str(sub_res) + aft
            else:
                return final(formula)
    
    def calc(formula):
        while True:
            val = re.split('(([^()]+))',formula,1)
            if len(val) == 3:
                berfor, centent, after = val
                new_content = mul_div(centent)
                formula = berfor + str(new_content) + after
            else:
                return mul_div(formula)
    
    
    if __name__ == '__main__':
        formula = "1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))"
        result = calc(formula)
        print(result) 
  • 相关阅读:
    中国年薪 ¥30 万和美国年薪$ 10 万的生活水平异同
    汽车之家CMDB设计思路 – 汽车之家运维团队博客
    平民软件 | 中间件
    FIT2CLOUD
    ZeroBrane Studio
    新炬网络-领先数据资产运营商 | 数据资产管理 | 数据库运维 | 自动化运维
    中国(南京)软件开发者大会
    夏仲璞 | 全球软件开发大会北京站2016
    Nginx下流量拦截算法 | 夏日小草
    docker~dockertoolbox的加速器
  • 原文地址:https://www.cnblogs.com/jl-bai/p/5498326.html
Copyright © 2011-2022 走看看