zoukankan      html  css  js  c++  java
  • python常用模块之re模块(正则)

    python种的re模块常用的5种方法,分别是re.match   re.search  re.findall  re.split  re.sub。

    在介绍五种方法之前,需要介绍一下正则的基础。

    .  表示任意字符,除
    以为
    
      转义字符
    
    [...] 字符集,表示取其中任意一个字符。比如[abc]d 可以匹配到ad bd cd。
    
    d  表示数字,等同于[0-9]
    
    D 表示非数字 [^d]
    
    s  表示空格
    
    S   表示非空格
    
    w  表示单词字符 [a-zA-z_0-9]
    
    W 表示非单词字符 [^w]
    
    
    * 匹配前面0个或多个字符
    
    + 匹配前面1个或多个字符
    
    ? 匹配前面0个或1个字符
    
    {m} 匹配前面m个字符
    
    {m,n} 匹配前1个字符m至n次
    
    ^  匹配以什么开头
    
    $  匹配以什么结尾
    
    A 匹配以什么开头
    
     匹配以什么结尾
    
    |  或  左右表达式取一个 ABC|def
    
    (..) 表示一个整体,(abc){2}  匹配abc2次
    
    (?P<name>)分组命名  比如(?P<name>tom)
    
    (number) 引用编号为number的分组 比如:(d)abc1  1abc1 
     
    

      

    上述介绍了正则的一些基本语法。下面介绍的是re模块的常用方法。

    一,re.match   尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

    re模块可以直接使用对应的方法,比如

    import re

    res = re.match('d+','123abc123')
    if res:
    print(res.group())

    这样就可以匹配到就是123,所以输出的则是123.

    但是一般使用re模块的步骤通常是 将正则表达式的字符串编译为pattern实例,然后使用pattern实例处理文本并获得匹配结果,最后使用对应方法处理。通俗的就是要使用正则,先创建正则规则,然后编译成对象。最种使用正则的对应方法处理即可。

    这样的好处就是速度更快。

    所以上述代码更新为:

    import re
    pattern = re.compile('d+')
        res = re.match(pattr, '123abc123')
        if res:
            print(res.group()) 

    为了更直观的显示时间的区别,附上时间差的对比:

    import time
    import re
    def timeer(fun):
        def wrapper():
            start_time = time.time()
            fun()
            stop_time = time.time()
            print('{0}函数执行时间为{1}'.format(fun.__name__,stop_time-start_time))
        return  wrapper
    @timeer
    def re_compile():
        pattern = re.compile('d+')
        res = re.match(pattern, '123abc123')
        if res:
            print(res.group())
    @timeer
    def re_nocompile():
    
        res = re.match('d+', '123abc123')
        if res:
            print(res.group())
    re_compile()
    
    re_nocompile()
    

    上面的re.group()这里其实是可以填写对应的数值的。默认就是0,代表输出匹配到所有字符。

    import re

    pattern = re.compile('(d+)([a-z]+)(d+)')

    res = re.match(pattern,'123abc123')

    if res:
    print(res.group(0))
    print(res.group(1))
    print(res.group(2))
    print(res.group(3))
    print(res.groups())
    
    

    0 表示输出匹配到的所有,即默认所以输出的结果为123abc123

    1 表示输出第一个括号匹配到的内容,即123

    2表示输出第二个括号匹配到的内容,即abc

    3表示输出第三个括号匹配到的内容,即123

    groups() 返回所有小组匹配到的内容,以元祖的形式输出。即(123,abc,123)

    切记:match是从第一字符开始匹配,如果匹配不到,直接返回None.

    二,re.search  

    re.search  扫描整个字符串并返回第一个成功的匹配

    import re
    pattern = re.compile('[a-z]+(d+)(w+)')

    res = re.search(pattern,'123abc123_')

    if res:
    print(res.group())
    print(res.group(1))
    print(res.group(2))


    输出结果:
    abc123_
    123
    _

    可以发现,即使search没有匹配到123,但是它还是会往后匹配,而不是直接返回none。再看如下代码:

    import re
    pattern = re.compile('[a-z]+')
    
    res = re.search(pattern,'123abc123abd')
    
    if res:
        print(res.group())
    输出结果:abc

    可见,search匹配整个字符串,找到第一个就会输出。后面的则不匹配。

    简单小结:

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

    三,re.findall   在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。findall是没有group方法的。

    import re
    pattern = re.compile('[a-z]+')
    
    res = re.findall(pattern,'123abc123abd')
    
    print(res)
    
    
    输出结果:['abc', 'abd']
    

    可见该正则会将匹配到内容按列表的形式输出,它不仅仅是匹配一次,这个是它和search的区别 

    四, re.split 匹配分割字符串

    import re
    pattern = re.compile('[a-z]+')
    
    res = re.split(pattern,'123abc123abd')
    
    print(res)
    
    
    输出结果:['123', '123', '']
    

      

    五, re.sub 匹配替换

    import re
    
    pattern = re.compile('[a-z]+')
    
    res = re.sub(pattern,'000','123abc123')
    
    print(res)
    
    
    输出结果:123000123
    

      

     值得注意的是:正则中* + 都是贪婪匹配,?是非贪婪匹配。所以如果你要想要限制住*的贪婪匹配,可以在*的后面添加?来限制。比如
     
    line = '手机号:15200000000,生日:0802'
    reg_str1 = '.*:'
    reg_str2 = '.*?:'
    
    match_obj1 = re.match(reg_str1,line)
    match_obj2 = re.match(reg_str2,line)
    
    if match_obj1:
        print(match_obj1.group())
    
    
    if match_obj2:
        print(match_obj2.group())
    
    输出结果:
    手机号:15200000000,生日:
    手机号:
    
    
    可见,?是可以限制住*的贪婪匹配的!!!
    

      

    装b可用:分组,可以给匹配到的内容设置名称生成字典。
     
    import re
    re = re.search('(?P<id>[0-9]+)(?P<name>[a-zA-Z]+)','abcd1233bob@34')
    if re:
        print(re.group())
        print(re.groupdict())
    
    
    
    输出结果:
    1233bob
    {'id': '1233', 'name': 'bob'}
    
    #比如匹配身份证,
    import re
    
    id = '360201199011113721'
    
    res = re.search('(?P<Province_code>[0-9]{2})(?P<City_code>[0-9]{2})(?P<County_code>[0-9]{2})(?P<birthday>[0-9]{8})(?P<policestation_id>[0-9]{2})(?P<sexid>[0-9]{1})(?P<checkid>[0-9]{1})',id)
    
    if res:
        print(res.group())
        print(res.groupdict())
    
    
    输出结果:
    360201199011113721
    {'Province_code': '36', 'City_code': '02', 'County_code': '01', 'birthday': '19901111', 'policestation_id': '37', 'sexid': '2', 'checkid': '1'}
    

      

      

  • 相关阅读:
    MySQL学习笔记(12):触发器
    MySQL学习笔记(11):存储过程和函数
    MySQL学习笔记(10):视图
    MySQL学习笔记(9):索引
    MySQL学习笔记(8):字符集
    MySQL学习笔记(7):存储引擎
    MySQL学习笔记(6):常用函数
    MySQL学习笔记(5):运算符
    MySQL学习笔记(4):数据类型
    MySQL学习笔记(3):SQL
  • 原文地址:https://www.cnblogs.com/lin1/p/8979456.html
Copyright © 2011-2022 走看看