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

    正则表达式

    一、简介:
    正则表达式:是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现,需要在文件最开始的地方用import re来引入。正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎-执行。


    二、字符匹配(普通字符,元字符):


    普通字符:大多数字符和字母都会和自身匹配
    >>> re.findall('alex','yuanaleSxalexwupeiqi')
    ['alex']


    元字符:
        .    ^    $    *     +     ?     { }     [ ]     |     ( )    

     

     示例:

    >>> re.findall(r"a(d+)b","a23b")
            ['23']
    >>> re.findall(r"a(d+?)b","a23b") 
            ['23']

     [ ]:

    元字符[]表示字符类,在一个字符类中,只有字符^、-、]和有特殊含义。
    字符仍然表示转义,字符-可以定义字符范围,字符^放在前面,表示非,取反。

    >>> re.findall(r"a[bc]d","wwwwabcd")
    []
    >>> re.findall(r"a[bcd]e","wwwwabcde")
    []
    >>> re.findall(r"a[bcd]e","wwwwade")
    ['ade']
    >>> re.findall(r"a[bc]d","wwwwabd")
    ['abd']
    >>>
    >>> re.findall(r"a[.]d","wwwwabd")
    []
    >>> re.findall(r"a[.]d","wwwwa.d")
    ['a.d']
    >>> re.findall(r"[a-z]","wwwwa.d")
    ['w', 'w', 'w', 'w', 'a', 'd']
    >>> re.findall(r"[1-9]","ww3ww8a.d")
    ['3', '8']

     | :或    

     注:(?:a|b)使用方法

    ret = re.findall('www.(baidu|laonanhai).com','sdad www.baidu.com')
    print(ret)
    #打印结果:['baidu']
    ret = re.findall('www.(baidu|laonanhai).com','sdad www.laonanhai.com')
    print(ret)
    #打印结果:['laonanhai']
    ret = re.findall('www.(?:baidu|laonanhai).com','sdad www.laonanhai.com')
    print(ret)
    #打印结果:['www.laonanhai.com']

    [^]:取反

    >>> re.findall(r"[^1-9]","ww3ww8a.d")
    ['w', 'w', 'w', 'w', 'a', '.', 'd']
    >>> re.findall(r"[^1-9]","ww3ww8a.d0")
    ['w', 'w', 'w', 'w', 'a', '.', 'd', '0']

    特殊符号:

    ”^“ “ $ ”分别指出一个字符串的开始和结束。

    示例:

    “^The”:表示以“The”开始的字符串

    “ok$”:表示以“ok”结束的字符串

    d 匹配任何十进制数;它相当于类 [0-9]。
    D 匹配任何非数字字符;它相当于类 [^0-9]。
    s 匹配任何空白字符;它相当于类 [ fv]。
    S 匹配任何非空白字符;它相当于类 [^ fv]。
    w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
    W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]
    : 匹配一个单词边界,也就是指单词和空格间的位置。

    只是匹配字符串开头结尾及空格回车等的位置, 不会匹配空格符本身 

    示例:

    s,w,d:

    >>> re.findall(r"s","ww3w w8a.d0")
    [' ']
    >>> re.findall(r"w","ww3ww8a.d0")
    ['w', 'w', '3', 'w', 'w', '8', 'a', 'd', '0']
    >>> re.findall(r"d","ww3ww8a.d0")
    ['3', '8', '0']

    :

    >>> re.findall(r"abc","abcsdsadasabcasdsadasdabcasdsa")
    []
    >>> re.findall(r"abc","abc sdsadasabcasdsadasdabcasdsa")
    ['abc']
    >>> re.findall(r"abc"," abc sdsadasabcasdsadasdabcasdsa")
    ['abc']

     

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

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

    三、函数:

    匹配开头

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

    >>> re.match('com', 'comwww.runcomoob').group()
    'com'
    >>> re.match('com', 'Comwww.runComoob',re.I).group()
    'Com'

    re.I 使匹配对大小写不敏感
    re.L 做本地化识别(locale-aware)匹配
    re.M 多行匹配,影响 ^ 和 $
    re.S 使 . 匹配包括换行在内的所有字符

    分组:

    #无分组:
    origin = "hello alex bcd alex lge alex acd 19"
    r = re.match("hw+",origin)
    print(r.group())
    #打印结果:hello
    
    #有分组:是将group中的值再匹配括号中的(从左到右,从外到里),有几个括号就取几个
    origin = "hello alex bcd alex lge alex acd 19"
    r = re.match("(h)(w+)",origin)
    print(r.groups())
    #打印结果:('h', 'ello')
    
    #?P<>设置groupdict中的key
    origin = "hello alex bcd alex lge alex acd 19"
    r = re.match("(?P<k1>h)(?P<k2>w+)",origin)
    print(r.groupdict())
    #打印结果:{'k1': 'h', 'k2': 'ello'}

    匹配第一个

    search(search有无分组情况和match一样):re.search(pattern, string, flags=0)

    >>> re.search('dcom', 'www.4comrunoob.5com').group()
    '4com'

    注意:
    re.match('com', 'comwww.runcomoob')
    re.search('dcom', 'www.4comrunoob.5com')
    一旦匹配成功,就是一个match object 对象,而match object 对象拥有以下方法:
    group() 返回被 RE 匹配的字符串
    start() 返回匹配开始的位置
    end() 返回匹配结束的位置
    span() 返回一个元组包含匹配 (开始,结束) 的位置


    group() 返回re整体匹配的字符串,可以一次输入多个组号,对应组号匹配的字符串。
    1. group()返回re整体匹配的字符串,
    2. group (n,m) 返回组号为n,m所匹配的字符串,如果组号不存在,则返回indexError异常
    3.groups() 方法返回一个包含正则表达式中所有小组字符串的元组,从 1 到所含的小组号,通常groups()不需要参数,返回一个元组,元组中的元就是正则表达式中定义的组。

    >>> a = "123abc456"
    >>> re.search("([0-9]*)([a-z]*)([0-9]*)",a).groups() ('123', 'abc', '456')
    group(0) 列出所有括号匹配部分,group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3)列出第三个括号匹配部分。
    import re
    >>> a = "123abc456"
    >>> re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)
    '123abc456'
    >>> re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1)
    '123'
    >>> re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2)
    'abc'
    >>> re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3)
    '456'

    获取字符串中所有匹配项

    findall:可以获取字符串中所有匹配的字符串,以列表形式返回所有匹配的字符串。

    findall在有组的情况下,只匹配组里的情况,以列表形式返回。如果两个组分别匹配到组里的情况,就将作为一个元祖返回给列表。

    import re
    print(re.findall(r"a(d+)b","a23b"))
    #打印结果:['23']
    print(re.search(r"a(d+)b", "a23b").group())
    #打印结果:a23b
    >>> p = re.compile(r'd+')
    >>> print p.findall('one1two2three3four4')
    ['1', '2', '3', '4']
    >>> re.findall(r'd+','one1two2three3four4')
    ['1', '2', '3', '4']

     有无分组情况:

    origin = "hello alex alex bcd abcd lge acd 19"
    r = re.findall("aw+",origin)
    r1 = re.findall("(aw+)",origin)
    r2 = re.findall("(a)(w+)",origin)
    print(r)
    print(r1)
    print(r2)
    #打印结果:
    ['alex', 'alex', 'abcd', 'acd']
    ['alex', 'alex', 'abcd', 'acd']
    [('a', 'lex'), ('a', 'lex'), ('a', 'bcd'), ('a', 'cd')]
    
    
    origin = "hello ax lex bed alex lge alex acd 19"
    n = re.findall("(a)(w)*" , origin)
    print(n)
    #打印结果:[('a', 'x'), ('a', 'x'), ('a', 'x'), ('a', 'd')]

    *:0-多次,默认情况是贪婪的。有分组,取多次,默认取最后一个值,如果后面没有符合项,会匹配空

    a = "alex"
    n = re.findall("(w)(w)(w)(w)",a)
    print(n)
    n1 = re.findall("(w)",a)
    print(n1)
    n2 = re.findall("(w)*",a)
    print(n2)
    #打印结果:
    [('a', 'l', 'e', 'x')]
    ['a', 'l', 'e', 'x']
    ['x', '']
    
    n = re.findall("(dasd)","lasd2asdp3asd98kif")
    print(n)
    #打印结果:['2asd', '3asd']
    n = re.findall("(dasd)*","lasd2asdp3asd98kif")
    print(n)
    #打印结果:['', '', '', '', '2asd', '', '3asd', '', '', '', '', '', '']

    空格匹配:如果没有匹配到空格,将返回空内容,并且会返回自身

    #1、匹配到符合项之后再从符合项之后开始匹配
    n = re.findall("d+wd+","a2b3c4d5")
    print(n)
    #打印结果:['2b3', '4d5']
    
    #2、空格匹配(字符串中有八个字符,返回了九个空格)
    n = re.findall("","a2b3c4d5")
    print(n)
    #打印结果:['', '', '', '', '', '', '', '', '']

    re.compile(strPattern[, flag]):

    >>> text = "JGood is a handsome boy, he is cool, clever, and so on..."
    >>> regex = re.compile(r'w*oow*')
    >>> print regex.findall(text)
    ['JGood', 'cool']

    sub :替换

    re.sub(pattern, repl, string, max=0)

    >>> re.sub("g.t","have",'I get A,  I got B ,I gut C')
    'I have A,  I have B ,I have C'
    >>> re.sub("g.t","have",'I get A,  I got B ,I gut C',2)
    'I have A,  I have B ,I gut C'

    subn:返回替换次数

    >>> re.subn("g.t","have",'I get A,  I got B ,I gut C')
    ('I have A,  I have B ,I have C', 3)

    split:分割

    >>> p = re.compile(r'd+')
    >>> p.split('one1two2three3four4')
    ['one', 'two', 'three', 'four', '']
    >>> re.split('d+','one1two2three3four4five')
    ['one', 'two', 'three', 'four', 'five']

     有无分组情况:

    #无分组:
    origin = "hello alex bcd abcd lge acd 19"
    n = re.split("aw+",origin)
    print(n)
    #打印结果:['hello ', ' bcd ', ' lge ', ' 19']
    
    #有分组:
    n = re.split("a(w+)",origin)
    print(n)
    #打印结果:['hello ', 'lex', ' bcd ', 'bcd', ' lge ', 'cd', ' 19']
    
    #添加参数2:2是最大分割次数
    n = re.split("a(w+)",origin,2)
    print(n)
    #打印结果:['hello ', 'lex', ' bcd ', 'bcd', ' lge acd 19']

    finditer:finditer(string[, pos[, endpos]]) | re.finditer(pattern, string[, flags]): 

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

    >>> p = re.compile(r'd+')
    >>> iterator = p.finditer('12 drumm44ers drumming, 11 ... 10 ...')
    >>> for match in iterator:
    ...  match.group() , match.span()
    ...
    ('12', (0, 2))
    ('44', (8, 10))
    ('11', (24, 26))
    ('10', (31, 33))
    w = re.finditer(r'd+','12drumm44ers drumming, 11...10...')
    for aa in w:
        print(aa.group())
    #打印结果:
    12
    44
    11
    10

    练习:计算器计算:

    1 - 2 * ( (60 - 30 + (-40.0/5) * (9 - 2 * 5/3 + 7 / 3 * 10/4*2 +10 *5/14)) -(-4*3)/(16-3*2))
     1 import re
     2 
     3 
     4 def add_op(arg):  # 定义加法函数
     5     arg = arg.replace("++", "+").replace("--", "+").replace("+-", "-").replace("-+", "-")  # 替换符号
     6     num = re.findall("([+-]?d+.?d*)", arg)  #匹配所有数字
     7     result = 0
     8     for i in num:   #循环数字列表进行累加
     9         result = result + float(i)
    10     return result
    11 
    12 def mul(arg):   #定义乘除函数
    13     while True:
    14         result = re.split("(d+.?d*[*/][+-]?d+.?d*)",arg,1) #匹配乘法或除法
    15         if len(result) == 3:
    16             bef,cen,aft = result
    17             if "*" in cen:  #判断乘号是否在cen里面
    18                 num1,num2 = cen.split("*")  #将乘号进行分割得到乘数
    19                 new_cen = float(num1) * float(num2)     #将乘数相乘得到乘积
    20                 arg = bef +str(new_cen) + aft   #将乘积放入新的字符串表达式
    21             elif "/" in cen:    #判断除号是否在cen里面
    22                 num1,num2 = cen.split("/")  #分割除号得到除数和被除数
    23                 new_cen = float(num1) / float(num2)     #进行除法运算
    24                 arg = bef + str(new_cen) + aft      #将商放入新的字符串表达式
    25         else:
    26             return add_op(arg)
    27 
    28 def calc(arg):
    29     while True:
    30         arg = arg.replace(" ","")
    31         result = re.split("(([^()]+))",arg,1)     #匹配最里面的括号并且只取括号中的内容
    32         if len(result) == 3:
    33             bef,cen,aft = result
    34             # 计算括号中的表达式,先乘除后加减,得到计算结果
    35             r = mul(cen)
    36             #使用计算结果组成新的字符串表达式
    37             arg = bef + str(r) + aft
    38         else:   #计算完括号后开始按照先乘除再加减的运算
    39             return mul(arg)
    40 
    41 origin = "1 - 2 * ( (60 - 30 + (-40.0/5) * (9 - 2 * 5/3 + 7 / 3 * 10/4*2 +10 *5/14)) -(-4*3)/(16-3*2))"
    42 r = calc(origin)
    43 print(r)
    44 print(eval(origin))
  • 相关阅读:
    9. 如何在控制器或模型中获取当前登录的管理员或登录用户信息
    FastAdmin控制管理员只显示自己添加的数据
    div 隐藏
    使用JavaScript实现Input输入数据后自动计算并实时显示
    thinkphp中在页面怎么格式输出小数和时间
    fastadmin表单提交提示红色OK
    在某个域被使用或改变时,它会改变颜色。【用于提示表单已填充】
    Unix命令行学习
    Ubuntu菜鸟入门(十)—— Flash控件安装
    Ubuntu菜鸟入门(九)—— 支付宝支付控件安装
  • 原文地址:https://www.cnblogs.com/0820-zq/p/5498134.html
Copyright © 2011-2022 走看看