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

    1 元字符:

    1.1 .

    .除了换行符以外的任何单个字符

    1.2 ^

    ^只匹配起始字符

    temp1=re.findall('^morra','nsudi werwuirnmorra')
    temp2=re.findall('^morra','morransudi werwuirn')
    
    print(temp1)    #[]
    print(temp2)    #['morra']
    

    1.3 $

    $只匹配结尾字符

    temp2=re.findall('morra$','morransudi werwuirn')
    temp1=re.findall('morra$','nsudi werwuirnmorra')
    
    print(temp1)    #['morra']
    print(temp2)    #[]
    

    1.4 *

    *匹配0到多次,等同于{0,}

    temp1=re.findall('morra*','wwwmorr')
    temp2=re.findall('morra*','wwwmorra')
    temp3=re.findall('morra*','wwwmorraa')     #贪婪匹配
    
    print(temp1)    #['morr']
    print(temp2)    #['morra']
    print(temp3)    #['morraa']
    

    1.5 +

    +匹配1到多次,{1,}

    temp1=re.findall('morra+','wwwmorr')
    temp2=re.findall('morra+','wwwmorra')
    temp3=re.findall('morra+','wwwmorraa')
    
    print(temp1)    #[]
    print(temp2)    #['morra']
    print(temp3)    #['morraa']
    

    1.6 ?

    ?匹配0到1次,{0,1}

    temp1=re.findall('morra?','wwwmorr')
    temp2=re.findall('morra?','wwwmorra')
    temp3=re.findall('morra?','wwwmorraa')
    
    print(temp1)    #['morr']
    print(temp2)    #['morra']
    print(temp3)    #['morra']
    

    1.7 { }

    { }自定义匹配次数:{1}匹配1次,{1,2}匹配1到2次

    temp1=re.findall('morra{0}','wwwmorr')
    temp2=re.findall('morra{2}','wwwmorra')
    temp3=re.findall('morra{2}','wwwmorraa')
    
    print(temp1)    #['morr']
    print(temp2)    #[]
    print(temp3)    #['morraa']
    

    1.8 [ ]

    [ ]字符集,只匹配单个字符

    temp2=re.findall('morr[ab]','wwwmorra')
    temp3=re.findall('morr[ab]','wwwmorrab')
    
    print(temp2)    #['morra']
    print(temp3)    #['morra']
    

    注意:元字符在字符集里就不再具有特殊意义,变成了普通字了,但是d w s除外

    temp4=re.findall('morr[?]','wwwmorr?')    #['morr?']
    temp1=re.findall('[ab]','wwwmorrab.ab')    #['a', 'b', 'a', 'b']
    temp2=re.findall('[1-9]','wwwmorr1234')    #['1', '2', '3', '4']
    
    例外
    temp5 = re.findall('[d]', 'www.m12orr1234')      #['1', '2', '1', '2', '3', '4']
    temp6 = re.findall('[w]', 'www.m12')      #['w', 'w', 'w', 'm', '1', '2']
    temp7 = re.findall('[s]', 'www.m12or r1234')      #[' ']
    

    1.9 ^

    ^反向匹配
    temp1=re.findall('[^1-9]','www.m12orr1234') #匹配除数字意外的所有字符
    print(temp1) #['w', 'w', 'w', '.', 'm', 'o', 'r', 'r']

    1.10

    是最重要的元字符,可实现的功能如下:
    (1) 后面跟元字符就是去除其特殊功能。
    (2) 后面跟普通字符可以实现一些特殊功能,
    (3) 引用序号对应的字组所匹配的字符串。

    1.10.1 后面跟元字符就是去除其特殊功能。
    temp1 = re.findall('$', 'www.m12$orr1234')
    print(temp1)    #['$']
    
    1.10.2 后面跟普通字符可以实现一些特殊功能。

    可实现的功能如下:
    d 匹配任何单个十进制数,等同于[0-9],如果想匹配多个可以使用dd,d+,d{2}

    temp1 = re.findall('d', 'www.m12orr1234')
    temp2 = re.findall('dd', 'www.m12orr1234')
    temp3 = re.findall('ddd', 'www.m12orr1234')
    temp4 = re.findall('d{2,3}', 'www.m12orr1234')  # 匹配2次,或3次
    
    print(temp1)  # ['1', '2', '1', '2', '3', '4']
    print(temp2)  # ['12', '12', '34']
    print(temp3)  # ['123']
    print(temp4)  # ['12', '123']
    

    D 匹配任何非数字字符,等同于[^0-9]
    s 匹配任何空白字符,等同于[ fv]
    S 匹配任何非空白字符,等同于[^ fv]
    w 匹配任何字母数字字符,等同于[A-Za-z0-9]
    W 匹配任何非字母数字字符,等同于[^A-Za-z0-9]
     匹配一个单词边界,也就是指单词和空格间的位置

    temp = re.findall(r"abc", "asdas abc 1231231")
    print(temp)     #['abc']
    
    temp = re.findall("abc\b", "asdas abc 1231231")
    print(temp)     #['abc']
    
    temp = re.findall(r"abc", "asdas*abc*1231231")
    print(temp)     #['abc'],同样也可以识别特殊字符和单词之间的边界
    
    temp = re.findall(r"abc2", "asdas*abc2*31231")
    print(temp)     #['abc2'],同样也可以识别特殊字符和单词之间的边界
    
    temp = re.findall(r"I", "I MISS IOU")
    print(temp)     #['I', 'I']
    
    1.10.3 引用序号对应的字组所匹配的字符串。
    temp = re.search(r'(alex)(eric)com1', 'alexericcomalex').group()   #alexericcomalex,1就是第一组等同于alex
    temp2 = re.search(r'(alex)(eric)com2', 'alexericcomeric').group()  #alexericcomeric,2就是第二组等同于eric
    

    2 正则函数

    返回一个对象:match、search、finditer
    返回一个列表:findall、split

    2.1 match

    match,从头匹配,使用的比较多

    def match(pattern, string, flags=0):
        """
        match(规则,字符串,标志位)
        flag(标志位)用于修改正则表达式的匹配方式,常见的工作方式如下:
        re.I    使匹配对大小写不敏感
        re.L    做本地化识别(local-aware)匹配
        re.M    多行匹配,影响^和$,不匹配换行符
        re.S    使.匹配包括换行在内的所有字符
        """
        
        """Try to apply the pattern at the start of the string, returning
        a match object, or None if no match was found."""
        return _compile(pattern, flags).match(string)
    

    2.2search

    匹配字符串,匹配到一个后,就不再往下匹配了。

    - 非贪婪匹配
    从前面可以看到'*','+','?'都是贪婪的。但是一旦在d+后面加上?之后,就表示非贪婪匹配。

    temp = re.search(r'a(d+?)','a23b').group()   #a2
    temp = re.search(r'a(d+?)b','a23b').group()    #ab,当()再a、b中间的时候?的作用失效,整个匹配又成了贪婪模式
    match()
    
    
    

    2.3findall

    将所有匹配到的所有内容都放置在一个列表中。

    2.3.1 findall的优先匹配原则

    findall与search、match等不同的是,他会优先取组里的内容,可以使用?:来关闭

    temp = re.findall(r"www.(bing|google).com", "123 www.bing.com123www.google.com123")
    print(temp)        #['bing', 'google'],只把组里的内容匹配到了
    
    temp = re.findall(r"www.(?:bing|google).com", "123 www.bing.com123www.google.com123") 
    print(temp)        #['www.bing.com', 'www.google.com'],#在(后面加上?:可以关闭findall的优先捕获功能
    

    2.3.2 匹配顺序

    一旦有字符被匹配到,就会把匹配到的字符拿走,然后再匹配剩下的字符,如下。

    n = re.findall("d+wd+","a2b3c4d5")
    print(n)    #['2b3', '4d5'],
    

    2.3.3 匹配空值

    当匹配规则为空时,如果没有匹配到也会把空值放到结果中:

    n = re.findall("","a2b3c4d5")
    print(n)    #['', '', '', '', '', '', '', '', '']
    

    因此在写python正则的时候,要尽量使正则不为空

    n = re.findall(r"(w)+", "alex")    #推荐写法
    print(n)  # ['x']
    
    n = re.findall(r"(w)*", "alex")    #不推荐写法
    print(n)  # ['x','']
    

    2.3.4 findall的分组匹配

    temp = re.findall('a(d+)','a23b')    #['23']
    temp = re.findall('a(d+?)','a23b')    #['2'],非贪婪模式匹配
    temp = re.findall(r'a(d+?)b', 'a23b')  # ['23'],当()再a、b中间的时候?的作用失效,整个匹配又成了贪婪模式
    match()
    

    如果正则里有一个组,那么会把组里匹配到的元素加入到最终的列表里。
    如果正则里有一个组,会把元素合并到一个元组里,然后作为列表的一个元素。

    n = re.findall(r"(w)", "alex")
    print(n)  # ['a', 'l', 'e', 'x']
    
    n = re.findall(r"(w)(w)(w)(w)", "alex")
    print(n)  # [('a', 'l', 'e', 'x')],有几个括号就取几次
    
    n = re.findall(r"(w){4}", "alex")
    print(n)  # ['x'],有几个括号就取几次
    
    n = re.findall(r"(w)*", "alex")
    print(n)  # ['x',''],有几个括号就取几次
    

    2.4 finditer

    finditer返回的是个可迭代的对象

    p = re.compile(r'd+')
    source = '12  dsnjfkbsfj1334jnkb3kj242'
    w1 = p.finditer(source)
    w2 = p.findall(source)
    print(w1)       #<callable_iterator object at 0x102079e10>
    print(w2)       #['12', '1334', '3', '242']
    
    for match in w1:
        print(match.group(), match.span())
        """
        12 (0, 2)
        1334 (14, 18)
        3 (22, 23)
        242 (25, 28)
        """
    
    p = re.compile(r'd+')
    
    iterate = p.finditer('')
    for match in iterate:
        match.group(), match.span()
    

    2.5 分组匹配

    a = '123abc456'
    temp1 = re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(0)   #123abc456
    temp2 = re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(1)   #123
    temp3 = re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(2)   #abc
    temp4 = re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(3)   #456
    temp5 = re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(1,3)   #('123', '456')
    temp6 = re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(1,2,3)  #('123', 'abc', '456')
    
    print(temp1)
    print(temp2)
    print(temp3)
    print(temp4)
    print(temp5)
    print(temp6)
    

    match、search、findall都有两个匹配方式:简单匹配和分组匹配

    2.5.1 无分组:
    import re
    
    origin = "hello morra bcd morra lge morra acd 19"
    r = re.match("hw+", origin)
    
    print(r.group())    #hello,获取匹配到的所有结果
    print(r.groups())   #(),获取模型中匹配到的分组结果
    print(r.groupdict())    #{},获取模型中匹配到的分组中所有执行了key的组
    
    2.5.2 有分组:
    import re
    
    origin = "hello morra bcd morra lge morra acd 19"
    r = re.match("h(w+)", origin)
    
    print(r.group())    #hello,获取匹配到的所有结果
    print(r.groups())   #('ello',),获取模型中匹配到的分组结果
    print(r.groupdict())    #{},获取模型中匹配到的分组中所有执行了key的组
    
    
    2.5.3 多个分组
    import re
    
    origin = "hello morra bcd morra lge morra acd 19"
    r = re.match("(?P<n1>h)(?P<n2>w+)", origin)
    
    print(r.group())    #hello,获取匹配到的所有结果
    print(r.groups())   #('h', 'ello'),获取模型中匹配到的分组结果
    print(r.groupdict())    #{'n2': 'ello', 'n1': 'h'},获取模型中匹配到的分组中所有执行了key的组
    

    2.6 分割:

    def split(pattern, string, maxsplit=0, flags=0):
    
        return _compile(pattern, flags).split(string, maxsplit)
    #maxsplit=0,最多分割次数
    
    2.6.1 split优先匹配

    由于split和findall一样结果返回的是所有元素的列表,因此他和findall一样具有优先匹配特性

    2.6.2 有组与无组
    origin = "hello alex bcd abcd lge acd 19"
    n = re.split("aw+",origin,1)
    print(n)    #['hello ', ' bcd abcd lge acd 19'],无组分割,结果不含自己
    
    origin = "hello alex bcd abcd lge acd 19"
    n = re.split("(aw+)",origin,1)
    print(n)    #['hello ', 'alex', ' bcd abcd lge acd 19'],有组分割,结果会包含自己
    
    origin = "hello alex bcd abcd lge acd 19"
    n = re.split("a(w+)",origin,1)
    print(n)    #['hello ', 'lex', ' bcd abcd lge acd 19'],有组分割,结果会包含自己
    
    2.6.3 特殊情况分析
    temp = re.split('d+','one1two2three3four4')
    print(temp)     #['one', 'two', 'three', 'four', '']
    
    temp = re.split('d+','1one1two2three3four4')
    print(temp)     #['', 'one', 'two', 'three', 'four', '']
    
    temp = re.split('[bc]', 'abcd')
    print(temp)  # ['a', '', 'd']   #思考题
    

    2.7 替换:

    2.7.1 sub
    temp = re.sub('g.t', 'have', 'I get A,I got B,I gut C')  # I have A,I have B,I have C
    
    temp = re.sub('g.t', 'have', 'I get A,I got B,I gut C', count=0)  # I have A,I have B,I have C,count默认为0,全部替换
    
    temp = re.sub('g.t', 'have', 'I get A,I got B,I gut C', count=1)  # I have A,I got B,I gut C
    
    temp = re.sub('g.t', 'have', 'I get A,I got B,I gut C', count=2)  # I have A,I have B,I gut C
    temp = re.sub('g.t', 'have', 'I get A,I got B,I gut C', 2)  # I have A,I have B,I gut C
    
    temp = re.sub('g.t', 'have', 'I get A,I got B,I gut C', count=3)  # I have A,I have B,I have C
    temp = re.sub('g.t', 'have', 'I get A,I got B,I gut C', 3)  # I have A,I have B,I have C
    
    2.7.2 subn

    subn最后会统计被替换的次数:

    temp = re.subn('g.t', 'have', 'I get A,I got B,I gut C')  #('I have A,I have B,I have C', 3),一共被替换了三次
    

    2.8 编译:

    compile可以吧一个规则编译到一个对象里,在多次批量调用的时候比较方便

    text = "g123dwsdsam cool coolksf"
    regex = re.compile(r'w*oow*') 
    temp = regex.findall(text)  # 查找所有包含'oo'的单词
    print(temp)                #['cool', 'coolksf']
    

    3 应用

    3.1 计算器

    import re
    
    source = "1 - 2 * (( 60-30 + (-9-2-5-2*3-5/3-40*4/2-3/5+6*3)*(-9-2-5-2*5/3 +7/3*99/4*2998 + 10 * 568 /14)) -(-4*3)/(16-3*2))"
    temp = re.search("([^()]+)",source).group()       #匹配括号里的内容
    print(temp)
    
    
    source2 = '2**3'        #幂运算
    re.search('d+.?d*([*/]|**)d+.?d*',source2)      # d+.?d* 匹配一个数(整数或浮点数),[*/]|**匹配乘除,或幂运算
    print(source2)
    
    print(2**3)
    

    3.2 匹配IP

    source = "13*192.168.1.11212321334"
    temp= re.search(r"(([01]?d?d|2[0-4]d|25[0-5]).){3}([01]?d?d|2[0-4]d|25[0-5])",source).group()
    
    print(temp)     #192.168.1.112
    

    4 补充

    为了防止python语法和正则语法冲突,在正则匹配规则前面加前面建议加r

    temp = re.findall(r"abc", "asdas abc 1231231")
    print(temp)     #['abc']
    
    temp = re.findall("abc\b", "asdas abc 1231231")
    print(temp)     #['abc']
    
  • 相关阅读:
    js中undefined,null,NaN的区别
    js中数字计算精度
    BestCoder Round #32
    POJ 2299 求逆序对(归并排序或树状数组)
    POJ 2603
    CodeForces 515C
    POJ 1853 背包问题
    UVA 10115 子符串替换
    POJ 1155 树状dp
    HDU 2196 树状dp 求树中节点之间的最长距离
  • 原文地址:https://www.cnblogs.com/whatisfantasy/p/6014523.html
Copyright © 2011-2022 走看看