美文网首页Python全栈工程师
24.4-Python的re模块使用

24.4-Python的re模块使用

作者: BeautifulSoulpy | 来源:发表于2019-10-19 10:07 被阅读0次

    不必羡慕那些活的精彩快乐的人,他们其实并不比你优秀,他们只是减轻了对他人高度的感受性;从而活在自己的节奏里面;

    也不要去羡慕别人的精彩,我们已经获得够没有自我了;
    我们应该明白:取悦自己,永远比取悦替他人重要
    一个人活在世上,必须要有真正喜爱的事情,才活的才有意义!!

    总结:

    1. [\s()] []里面是或的意思;只要有就处理;
    2. subn 没有encode()方法; 元组不能被编码;返回元组;
    3. 分组() 中如果有?: 分组就不存在了,,,
    4. match、search函数可以返回match对象;findall返回字符串列表;finditer返回一个个match对象
    5. 分组与匹配各是各的; 看()包的对象是什么;
    6. groupdict() 命名分组返回字典 ,只有有名字 ?P<head> ,就可以进入到命名分组中;

    Python的正则表达式

    Re 模块简介

    re模块是python中处理正则表达式的一个模块,通过re模块的方法,把正则表达式pattern编译成正则对象,以便使用正则对象的方法

    常量
    flags 说明
    re.M 、 re.MULTILINE 多行模式
    re.S 、re.DOTALL 单行模式
    re.I 、re.IGNORECASE 忽略大小写
    re.X 、re.VERBOSE 忽略表达式中的空白字符 和 # 注释
    re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
    re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库

    使用 | 位或 运算开启 多种选项;

    方法
    1. re.compile(pattern[, flags]) 编译方法

    语法格式为:

    re.compile(pattern[, flags])
    

    参数:
    pattern : 一个字符串形式的正则表达式
    flags: 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:

    compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用

    正则表达式需要被编译,为了提高效率,这些编译后的结果被保存,下次使用同样的pattern的时候,就不需要再次编译。

    re的其它方法为了提高效率都调用了编译方法,就是为了提速。

    import re
    test = 'bottle bag\nbig\napple\nAPPLE'
    
    # 内部编译+匹配一步完成;
    matcher = re.match('bot',test,re.I)   
    print(matcher)
       
    # 手动编译,再去对正则进行匹配; 效率高;
    regex = re.compile('bot')   # 手动编译  编译后的正则表达式 
    matcher = regex.match(test)   # 匹配模式
    print(matcher)
    #--------------------------------------------------------------------------
    <re.Match object; span=(0, 3), match='bot'>
    <re.Match object; span=(0, 3), match='bot'>
    
    
    手动编译效率问题

    手动编译的效率远远高于自动编译

    import re,timeit
    
    reg = re.compile('<(?P<tagname>\w*)>.*</(?P=tagname)>')
    reg.match('<h1>xxx</h1>')
    
    print(timeit.timeit(setup='''import re; reg = re.compile('<(?P<tagname>\w*)>.*</(?P=tagname)>')''', stmt='''reg.match('<h1>xxx</h1>')''', number=1000000))
    print(timeit.timeit(setup='''import re''', stmt='''re.match('<(?P<tagname>\w*)>.*</(?P=tagname)>', '<h1>xxx</h1>')''', number=1000000))
    #-------------------------------------------------------------------
    0.2924321999998938
    0.7150975999993534
    
    单次匹配

    (1) re.match函数
    re.match 尝试从字符串的起始位置匹配一个模式,匹配成功re.match方法返回一个匹配的对象,否则返回None。

    re.match(pattern, string, flags=0)
    regex.match(string[, pos[, endpos]])
    match匹配从字符串的开头匹配,regex对象match方法可以重设定开始位置和结束位置。返回match对象
    fullmatch() 全匹配

    import re
    test = 'bottle bag\nbig\napple\nAPPLE'
    
    for i,c in enumerate(test,1):
        print((i-1,c),end='\n' if i%8==0 else ' ')
    print('_'*30)
    
    regex = re.compile('b.+')   # 手动编译  编译后的正则表达式 
    matcher = regex.match(test,7)   # 匹配模式, start = 7
    print(matcher)
    #--------------------------------------------------------------------------------------------------------
    (0, 'b') (1, 'o') (2, 't') (3, 't') (4, 'l') (5, 'e') (6, ' ') (7, 'b')
    (8, 'a') (9, 'g') (10, '\n') (11, 'b') (12, 'i') (13, 'g') (14, '\n') (15, 'a')
    (16, 'p') (17, 'p') (18, 'l') (19, 'e') (20, '\n') (21, 'A') (22, 'P') (23, 'P')
    (24, 'L') (25, 'E') ______________________________
    <re.Match object; span=(7, 10), match='bag'>
    
    

    (2) re.search方法
    re.search 扫描整个字符串并返回第一个成功的匹配,匹配成功re.search方法返回一个匹配的对象,否则返回None

    re.search(pattern, string, flags=0)
    regex.search(string[, pos[, endpos]])
    从头搜索直到第一个匹配,regex对象search方法可以重设定开始位置和结束位置,返回match对象

    import re
    test = 'bottle bag\nbig\napple\nAPPLE'
    
    for i,c in enumerate(test,1):
        pass
        #print((i-1,c),end='\n' if i%8==0 else ' ')
    print('_'*30)
    
    regex = re.compile('b.+')   # 手动编译  编译后的正则表达式 
    matcher = regex.search(test,0)   # 匹配模式 start = 1 ,end =
    print(matcher)
    #----------------------------------------------------
    <re.Match object; span=(0, 10), match='bottle bag'>     # 返回一个match对象;
    

    re.match与re.search的区别

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

    (3) re.fullmatch(pattern, string, flags=0)

    regex.fullmatch(string[, pos[, endpos]])
    整个字符串和正则表达式匹配

    #  re.fullmatch()
    import re
    test = 'bottle bag\nbig\napple\nAPPLE'
    
    for i,c in enumerate(test,1):
        pass
        #print((i-1,c),end='\n' if i%8==0 else ' ')
    print('_'*30)
    
    regex = re.compile('^b.+', re.S)   # 手动编译  编译后的正则表达式 
    matcher = regex.fullmatch(test)   # 匹配模式 start = 1 ,end =
    print(matcher)
    #----------------------------------------------------
    <re.Match object; span=(0, 26), match='bottle bag\nbig\napple\nAPPLE'>
    
    全文搜索
    (1) findall(string[, pos[, endpos]])方法 ->[]

    在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。
    参数:

    string : 待匹配的字符串。
    pos : 可选参数,指定字符串的起始位置,默认为 0。
    endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。
    查找字符串中的所有数字:

    import re
    test = 'bottle\nbag\nbig\napple\nAPPLE\nable'
    
    for i,c in enumerate(test,1):
        pass
        #print((i-1,c),end='\n' if i%8==0 else ' ')
    print('_'*30)
    
    matchers = re.findall('b.+', test)   # 手动编译  编译后的正则表达式 
    print(matchers)
    for x in matchers:
        print(type(x),x)
    #---------------------------------------------------
    ['bottle', 'bag', 'big', 'ble']
    <class 'str'> bottle
    <class 'str'> bag
    <class 'str'> big
    <class 'str'> ble
    
    
    (2) re.finditer(pattern, string, flags=0)

    regex.finditer(string[, pos[, endpos]])
    对整个字符串,从左至右匹配,返回所有匹配项,返回迭代器
    注意每次迭代返回的是match对象

    # 返回一个迭代器;
    import re
    test = 'bottle\nbag\nbig\napple\nAPPLE\nable'
    
    for i,c in enumerate(test,1):
        pass
        #print((i-1,c),end='\n' if i%8==0 else ' ')
    print('_'*30)
    
    matchers = re.finditer('b.+', test)   # 手动编译  编译后的正则表达式 
    print(matchers)
    for x in matchers:
        print(type(x),x)
    #-----------------------------------------------------
    <callable_iterator object at 0x000001BC65D593C8>
    <class 're.Match'> <re.Match object; span=(0, 6), match='bottle'>
    <class 're.Match'> <re.Match object; span=(7, 10), match='bag'>
    <class 're.Match'> <re.Match object; span=(11, 14), match='big'>
    <class 're.Match'> <re.Match object; span=(28, 31), match='ble'>
    
    匹配替换
    (1) re.sub(pattern, replacement, string, count=0, flags=0)

    regex.sub(replacement, string, count=0)
    使用pattern对字符串string进行匹配,对匹配项使用repl替换。
    replacement可以是string、bytes、function。

    # 替换
    import re
    test = 'bottle\nbag\nbig\napple\nAPPLE\nable'
    
    for i,c in enumerate(test,1):
        pass
        #print((i-1,c),end='\n' if i%8==0 else ' ')
    print(re.sub('b\w+e','www',test).encode())  # 
    #-----------------------------------------------------------------
    b'www\nbag\nbig\napple\nAPPLE\nawww'
    
    (2) re.subn(pattern, replacement, string, count=0, flags=0) ->()

    regex.subn(replacement, string, count=0)
    同sub返回一个元组(new_string, number_of_subs_made)

    subn 没有encode()方法; 元组不能被编码;

    # subn 没有encode()方法; 元组不能被编码;
    import re
    test = 'bottle\nbag\nbig\napple\nAPPLE\nable'
    
    for i,c in enumerate(test,1):
        pass
        #print((i-1,c),end='\n' if i%8==0 else ' ')
    print(re.subn('b\w+e','www',test))  # 
    #---------------------------------------------------------
    ('www\nbag\nbig\napple\nAPPLE\nawww', 2)
    
    (3) re.split(pattern, string[, maxsplit=0, flags=0])

    split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:
    str.split分割字符串 (默认是 \s+)

    # str.split分割字符串 (**默认是 \s+**) 
    import re
    test = 'bottle\n\t (bag)\nbig\napple\nAPPLE\nable'
    
    for i,c in enumerate(test,1):
        pass
        #print((i-1,c),end='\n' if i%8==0 else ' ')
    print(test.split())
    
    regex = re.compile('\s+')
    print(regex.split(test))
    #----------------------------------------------------
    ['bottle', '(bag)', 'big', 'apple', 'APPLE', 'able']
    ['bottle', '(bag)', 'big', 'apple', 'APPLE', 'able']
    
    regex = re.compile('[\s()]+')
    print(regex.split(test))
    #----------------------------------------------------
    ['bottle', 'bag', 'big', 'apple', 'APPLE', 'able']
    
    split 练习:提取每行的单词;
    s = '''01 bottle
    02 bag
    03        big1
    100         able'''
    
    import re
    
    print(re.split('\s+\d+\s+',s))
    print(re.split('[\s\d+]+',s))
    #---------------------------------------
    ['01 bottle', 'bag', 'big1', 'able']
    ['', 'bottle', 'bag', 'big', 'able']
    
    思路总结:
    1. 前面补字符(空格)法;
    

    分组()

    () 中如果有?: ,分组就不存在了,,,

    使用小括号的pattern捕获的数据被放到了组group中。
    match、search函数可以返回match对象;findall返回字符串列表;finditer返回一个个match对象

    如果pattern中使用了分组,如果有匹配的结果,会在match对象中

    1. 使用group(N)方式返回对应分组,1到N是对应的分组,0返回整个匹配的字串
    2. 如果使用了命名分组,可以使用group('name')的方式取分组
    3. 也可以使用groups()返回所有组
    4. 使用groupdict() 返回所有命名的分组
    # 分组
    import re
    test = 'bottle\n\t (bag)\nbig\napple\nAPPLE\nable'
    
    for i,c in enumerate(test,1):
        pass
        #print((i-1,c),end='\n' if i%8==0 else ' ')
    print('-'*30)
    
    regex = re.compile('(b\w+)')    # 分组包 match对象,groups就是(match,)
    result = regex.finditer(test)
    for x in result:
        print(x,x.groups())
    #-----------------------------------------------------------
    <re.Match object; span=(0, 6), match='bottle'> ('bottle',)
    <re.Match object; span=(10, 13), match='bag'> ('bag',)
    <re.Match object; span=(15, 18), match='big'> ('big',)
    <re.Match object; span=(32, 35), match='ble'> ('ble',)
    
    1. 分组与匹配各是各的; 看()包括的对象是什么;
    regex = re.compile('a?(b\w+)')    # 分组包 match对象,groups就是(match)
    result = regex.finditer(test)
    for x in result:
        print(x,x.groups())
    #-------------------------------------------------------
    <re.Match object; span=(31, 35), match='able'> ('ble',)             # match='able'>     groups= ('ble',)      
    
    2. 分组号 0->matcher  ; 1->分组1     
    
    
    3. 命名分组,只有有名字 ?P<head>  ,就可以进入到命名分组中;
    import re
    test = 'bottle\n\t (bag)\nbig\napple\nAPPLE\nable'
    
    for i,c in enumerate(test,1):
        pass
        #print((i-1,c),end='\n' if i%8==0 else ' ')
    print('-'*30)
    
    regex = re.compile('(?P<head>a)(?P<tail>b\w+)')    # 分组包 match对象,groups就是(match)
    result = regex.search(test)
    print(result.groups())
    print(result.group(0),result.group(1),result.group(2))
    print(result.groupdict())
    #-----------------------------------------------
    ('a', 'ble')
    able a ble
    {'head': 'a', 'tail': 'ble'}
    
    

    相关文章

      网友评论

        本文标题:24.4-Python的re模块使用

        本文链接:https://www.haomeiwen.com/subject/fmjgmctx.html