zoukankan      html  css  js  c++  java
  • [ python ] 正则表达式及re模块

    正则表达式

    正则表达式描述:

        正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个‘规则字符串’,这个‘规则字符串’用来
        表达对字符串的一种过滤逻辑。

      在线测试工具:http://tool.chinaz.com/regex/

      需要明确的是正则表达式只和字符串相关。

      正则表达式基础使用参考:http://tool.chinaz.com/regex/

    re 模块中常用功能函数

    1. compile()

    编译正则表达式模式,返回一个对象的模式。(可以把那些常用的正则表达式编译成正则表达式对象,这样可以提高一点效率。)

    格式:

    re.compile(pattern,flags=0)
    pattern: 编译时用的表达式字符串。
    flags 编译标志位,用于修改正则表达式的匹配方式
    

    实例:

    import re
    s1 = 'have a good day.'
    rr = re.compile("w*oow*")
    print(rr.findall(s1))   # 查看字符串中包含'oo'的单词
    
    # 执行结果:
    # ['good']
    re_compile.py

    2. match()

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

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

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

    实例:

    import re
    s1 = 'runnicegoodrunbetterrun'
    # rr = re.match('run', 'nicegoodrun better.run')
    r1 = re.match('run', 'runnicegoodrunbetterrun').group()
    r2 = re.match('run', 'Runnicegoodrunbetterrun', re.I).group()   # re.I 忽视大小写
    
    print('r1:', r1)
    print('r2:', r2)
    
    # 执行结果:
    # r1: run
    # r2: Run
    re_match.py

    3. search()

    re.search函数会在字符串内查找模式匹配,只要找到第一个匹配然后返回,如果字符串没有匹配,则返回None

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

    实例:

    import re
    s1 = 'run nice good run better rungood'
    rr = re.search("good", s1).group()    # 只会匹配到一个就直接返回
    print(rr)
    
    # 执行结果:
    # good
    re_search.py

    注意:
        match和search一旦匹配成功,就是一个 match object 对象,而match object对象有以下方法:

    •     group()  返回被 RE 匹配的字符串
    •     start()   返回匹配开始的位置
    •     end()      返回匹配结束的位置
    •     span()      返回一个元组包含匹配的位置
    •     group()   返回 re 整体匹配的字符串,可以一次输入多个组号,对应组号匹配的字符串。

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

    import re
    a = "123abc456"
    rr = re.compile("([0-9]*)([a-z]*)([0-9]*)")
    print('group(0):', rr.search(a).group(0))    # group(0) 返回正则匹配到的全部内容
    print('group(1):', rr.search(a).group(1))    # group(1) 列出第一个 ([a-z]*) 匹配到的部分
    print('group(2):', rr.search(a).group(2))    # group(2) 列出第二个 ([0-9]*) 匹配到的部分
    print('group(3):', rr.search(a).group(3))    # group(3) 列出第三个 ([0-9]*) 匹配到的部分
    print('groups():', rr.search(a).groups())    # groups() 以元组的形式列出每个括号中匹配到的内容
    
    # 执行结果:
    # group(0): 123abc456
    # group(1): 123
    # group(2): abc
    # group(3): 456
    # groups(): ('123', 'abc', '456')
    re_group.py

    4. findall()

    描述:
    re.findall 遍历匹配,可以获得字符串中所有匹配的字符串,返回一个列表

    格式:

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

    实例:

    import re
    
    p = re.findall("(d+)", 'asdf12sdf123ad')   # 当匹配到多个值,以列表的形式返回
    print(p)
    
    # 执行结果:
    # ['12', '123']
    
    
    import re
    
    tt = 'ggood booyy nice day'
    print(re.findall("w*oow*", tt))
    print(re.findall("(w)*oo(w)", tt))    # 通过小括号分组,得到列表中的元组
    
    # 执行结果:
    # ['ggood', 'booyy']
    # [('g', 'd'), ('b', 'y')]
    re_findall.py

    5. finditer()

    描述:

    搜索string,返回一个顺序访问每一个匹配结果(Match对象)的迭代器。找到RE匹配的所有部分,并把他们作为一个迭代器返回。

    格式:

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

    实例:

    import re
    
    iter = re.finditer('d+', 'adfasdfq2313sdasf2qe4123')
    for i in iter:
        print(i)    # finditer返回的是一个迭代器
        print(i.group())    # 返回一组匹配到的部分
        print(i.span())     # 返回一个元组包含匹配(开始,结束)的位置
    
    # 执行结果:
    # <_sre.SRE_Match object; span=(8, 12), match='2313'>
    # 2313
    # (8, 12)
    # <_sre.SRE_Match object; span=(17, 18), match='2'>
    # 2
    # (17, 18)
    # <_sre.SRE_Match object; span=(20, 24), match='4123'>
    # 4123
    # (20, 24)
    re_finditer.py

    6. split()

    描述:

    按照能够匹配的字串将 string 分割后返回列表。
    可以使用re.split来分割字符串,如:re.split(r's+', text);将字符串按空格分割成一个单词列表。

    import re
    print(re.split("s+", 'nice to meeting you'))
    
    # 执行结果:
    # ['nice', 'to', 'meeting', 'you']
    

    格式:

    re.split(pattern, string[, maxsplit])
    maxsplit用于指定最大分割次数,不指定将全部分割。

    实例:

    import re
    print(re.split('d+','one1two2three3four4five5'))
    
    # 执行结果:
    # ['one', 'two', 'three', 'four', 'five', '']
    
    
    re.split 用法在这里要注意下:
        当正则中使用分组和不使用分组返回的是不同的结果:
        
    import re
    print(re.split('[a-z]','111a222'))
    print(re.split('([a-z])','111a222'))
    
    # 执行结果:
    # ['111', '222']        # 未使用分组
    # ['111', 'a', '222']   # 使用分组
    re_split.py

    通过上面的例子,我们可以看到未使用分组和使用分组的不同,这里总结一下:

    当正则未使用分组(正则未带小括号)时,按照匹配到的部分进行切割,且匹配到的部分不会出现在结果列表中
    当正则使用分组(正则带小括号)时,按照匹配到的部分进行切割,匹配到的部分作为元素出现在列表中,且匹配到值的索引按照奇数位出现1、3、5、7...

    灵活的使用分组会带来很多的便捷,后面编写计算器的代码中就会用到。

    7. sub()

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

    格式:

    re.sub(pattern, repl, string, count)

    默认全部替换

    实例:

    import re
    s1 = '1 + 2 + (4 / 5  + 2)'
    
    print(re.sub(' ', '', s1))  # 直接去除计算表达式中的空格
    
    # 执行结果:
    # 1+2+(4/5+2)
    re_sub.py

    8. subn()

    描述:

    返回元组类型,最后一位为替换的次数

    格式:

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

    实例:

    import re
    s1 = '1 + 2 + (4 / 5  + 2)'
    
    print(re.subn(' ', '', s1))  # 直接去除计算表达式中的空格
    
    # 执行结果:
    # ('1+2+(4/5+2)', 9)    # 替换了9次空格
    re_subn.py

    re模块方法区分

    1. re.match与re.search与re.findall的区别:

    re.match     只是匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None
    re.search     匹配整个字符串,直到直到一个匹配。

    import re
    s1 = 'abc123'
    print(re.match("[d]", s1))     # 从头开始搜索数字,如果开始没有匹配到返回None
    print(re.search("[d]", s1).group())    # 从头开始搜索数字,匹配到第一个直接返回一个迭代器
    print(re.findall("[d]", s1))   # 遍历查找字符串中的数字部分,查找到每个数字都以元素的形式展现
    
    # 执行结果:
    # None
    # 1
    # ['1', '2', '3']
    re_match_search.py

    2. 贪婪匹配和非贪婪匹配

    *?,+?,??,{m,n}?    前面的*,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配

    实例1:

    import re
    a = re.findall(r"a(d+?)",'a23b')   # 在正则后面加'?',表示惰性匹配,匹配到一个就直接返回
    print(a)
    b = re.findall(r"a(d+)",'a23b')    # 贪婪匹配
    print(b)
    
    # 执行结果:
    # ['2']
    # ['23']
    实例1

    实例2:

    a = re.match('<(.*)>','<H1>title<H1>').group()
    print(a)
    b = re.match('<(.*?)>','<H1>title<H1>').group()
    print(b)
    
    # 执行结果:
    # <H1>title<H1>
    # <H1>
    实例2

    实例3:

    a = re.findall(r"a(d+)b",'a3333b')
    print(a)
    b = re.findall(r"a(d+?)b",'a3333b')
    print(b)
    
    # 执行结果:
    # ['3333']
    # ['3333']
    实例3

    参考链接:
        https://www.cnblogs.com/tina-python/p/5508402.html
        http://tool.chinaz.com/regex/
        http://www.cnblogs.com/Eva-J/articles/7228075.html#_label10

  • 相关阅读:
    Java下载文件,中文名乱码(attachment;filename=中文文件名)
    Spring Boot打jar包,排除lombok等scope=provided的依赖
    VirtualBox+WinDbg+Win7调试环境配置
    【编译原理】FIRST集、FOLLOW集算法原理和实现
    epoll EPOLLL、EPOLLET模式与阻塞、非阻塞
    【编译原理】提取左部公因子算法
    编译和阅读WRK源码
    WRK 源码编译使用
    Windows加载器与模块初始化
    关于Win7 x64下过TP保护(应用层)
  • 原文地址:https://www.cnblogs.com/hukey/p/9778369.html
Copyright © 2011-2022 走看看