zoukankan      html  css  js  c++  java
  • python正则表达式(re模块)

    python正则表达式(re模块)

    什么是正则表达式

    正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a到z之间的字母)和特殊字符(称为"元字符")。正则表达式使用但个字符串来描述、匹配一系列匹配某个句法规则的字符串。

    正则字符简单介绍

    普通字符

    普通字符包括没有显示指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其它符号

    特殊字符

    特别字符 描述
    $ 匹配输入字符串的结尾位置。如果设置了RegExp对象的Multline属性,则$也匹配' '或' '。
    () 匹配一个子表达式的开始和结束位置(匹配括号中的全部内容)。子表达式可以获取供以后使用。
    * 匹配前面的子表达式零次或多次。
    + 匹配前面的子表达式一次或多次(至少有一次)。
    . 匹配除换行符 之外的任何单词。
    [ ] 匹配括号中一个字符,范围描述 如[0-9 a-z A-Z]。
    ? 匹配前面的子表达式零次或一次,或指明一个非贪婪的限定。
    转义字符,如*表示匹配*号。
    ^ 匹配字符串的开始位置(用在[ ]时,可以理解为取反,表示不匹配中括号中的字符串)。
    {} 限定匹配的次数,如{n}表示匹配n个字符,{n,}表示至少匹配n个字符,{n,m}表示至少n个,最多m个(m和n均为非负整数)。
    | 两项中取一项。

    非打印字符

    非打印字符也可以是正则表达式的组成部分。

    字符 描述
     匹配一个单词边界,即字与空格间的位置。("This is Regex匹配单独的单词"is",正则就要写成"is")。
    d 匹配数字。
    w 匹配字母,数字,下划线。
    s 匹配空格。
    B 非单词边界匹配。
    D 匹配非数字。
    W 匹配非(字母,数字,下划线)。
    S 匹配非空格。

    量词

    量词的三个重要概念

    贪婪(贪心)如"*"字符,贪婪量词会首先匹配整个字符串,尝试匹配时,它会选定尽可能多的内容,如果失败则回退一个字符,然后再次尝试,回退的过程就叫做回溯,它会每次回退一个字符,直到找到匹配的内容或者没有字符可以回退。相比下面两种贪婪量词对资源的消耗是最大的。

    懒惰(勉强)如"?",懒惰量词使用另一种方法匹配,它从目标的起始位置开始尝试匹配,每检查一个字符,并寻找它要匹配的内容,如此循环直到字符串结尾处。

    占有如"+",占有量词很像贪心式量词,它会选择尽可能多的内容,然后尝试寻找匹配内容,但它只尝试一次,不会回溯。就好比先抓一把石头,然后从石头中挑出黄金。

    re模块中常用功能函数

    compile()

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

    re.compile(pattern,flags=0)

    pattern:编译时用的表达式字符串。

    flags:编译标志位,用于修改正则表达式,如:是否区分大小写,多行匹配等。常用的flags有:

    标志 含义
    re.S(DOTALL) 使.匹配包括换行符在内的所有字符。
    re.I(IGNORECASE) 是匹配对大小写不敏感。
    re.L(LOCALE) 做本地化识别(locale-aware)匹配,法语等。
    re.M(MULTILINE) 多行匹配,影响^和$。
    re.X(VERBOSE) 该标志通过给予更灵活的格式以便将正则表达式写的更易于理解。
    re.U 根据Unicode字符集解析字符,这个标志影响w、W、、B
    import re
    
    # 将正则表达式编译成pattern对象
    pattern = re.compile("d+")
    

    pattern对象的常用方法有:match()、search()、finall()、finder()、split()、sub()、subn()。

    (1)match()方法

    该方法用于查找字符串的头部,它只要找到一个匹配的结果就返回。(这个方法并不是完全匹配。当pattern结束时若string还要剩余字符,仍然视为成功。想要完全匹配,可以在表达式末尾加上边界匹配符'$')。

    match(pattern, string,pos=0,endpos=-1)
    

    说明:string是待匹配的字符串,pos和endpos指定字符串的起始和终点的位置,当不指定是,默认从头部开始匹配,当匹配成功是,返回Match对象。

    import re
    
    pattern = re.compile("\d+")
    match = pattern.match("aaa123bbb123ccc123")
    print(match)	# None(从头部开始匹配)
    
    match = pattern.match("aaa123bbb123ccc123", 3, 6)
    print(match) # <_sre.SRE_Match object; span=(3, 6), match='123'>
    
    print(match.group())	# 123,返回匹配的字符串,如果需要获得整个匹配的字符串时,可以使用group()或者group(0)
    print(match.start())	# 3,返回匹配的字串在整个字符串的起始位置
    print(match.end())	# 6,返回匹配的字串在整个字符串的结束位置
    print(match.span())	# (3, 6),返回(start(), end())
    

    (2) serach()方法

    search(pattern, string,pos=0,endpos=-1)
    

    说明:匹配成功时返回Match对象,匹配不成功时返回None。

    import re
    
    pattern = re.compile("\d+")
    match = pattern.search("aaaa1111bbbb1234cccc1243")
    print(match)	# <_sre.SRE_Match object; span=(4, 8), match='1111'>
    
    match = pattern.search("aaaa1111bbbb1234cccc1243", 3, 6)
    print(match)	# <_sre.SRE_Match object; span=(4, 6), match='11'>
    
    print(match.group())	# 11
    print(match.start())	# 4
    print(match.end())	# 6
    print(match.span())	# (4, 6)
    

    (3)findall()方法

    该方法返回所有的匹配结果。

    findall(pattern, string, pos, endpos=-1)
    

    说明:匹配成功,返回匹配的列表,匹配不成功,返回空列表。

    import re
    
    pattern = re.compile("\d+")
    match = pattern.findall("aaaa1111bbbb1234cccc1243")
    print(match)	# ['1111', '1234', '1243']
    

    (4)finditer()方法

    finditer(pattern, string, pos=0, endpos=-1)
    

    ​ 说明:匹配所有的字符串,返回所有匹配字符串,但是它返回的是一个迭代器,通过该迭代器我们可以访问匹配的每一个字符串。

    import re
    
    pattern = re.compile("\d+")
    result_iter = pattern.finditer("aaaa1111bbbb1234cccc1243")
    for result in result_iter:
        print("找得到字符串{},位置是{}".format(result.group(), result.span()))
    # 找得到字符串1111,位置是(4, 8)
    # 找得到字符串1234,位置是(12, 16)
    # 找得到字符串1243,位置是(20, 24)    
    

    (5)split()方法

    split(pattern, string, maxsplit=0)
    

    说明:用来分割字符串,maxsplit表示最大的分割次数,不指定即为全部分割。

    import re
    
    print(re.split('d+', 'one1two2three3four4five5'))
    # ['one', 'two', 'three', 'four', 'five', '']
    

    (6)sub()方法

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

    说明:该方法用来替换。rel如果为字符串,会使用rel替换字符串中的每一个匹配的子串,并且返回替换后的字符串;如果为函数,则该函数应该只接收一个Match对象,并且返回一个字符串用于替换。

    count用于指定替换次数。

    import re
    
    p = re.compile(r'(w+) (w+)')
    s = 'test aaa,test bbb'
    
    
    def func(m):
        return 'hei' + ' ' + m.group(2)
    
    
    print(p.sub(r'hello world', s))	# hello world,hello world(使用hello world替换)
    print(p.sub(r'2 1', s))   # aaa test,bbb test(1 上方第一个括号内的内容。)
    print(p.sub(func, s))	# hei aaa,hei bbb(替换全部)
    print(p.sub(func, s, 1))	# hei aaa,test bbb(最多只替换一次)
    

    (7)subn()方法

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

    说明:该方法也是用于替换,返回一个元祖,元祖有两个元素,第一个和使用sub方法返回的结果一样,count表示替换的次数。

    import re
    
    p = re.compile(r'(w+) (w+)')
    s = 'test aaa,test bbb'
    
    
    def func(m):
        return 'hei' + ' ' + m.group(2)
    
    
    print(p.subn(r'hello world', s))	# ('hello world,hello world', 2)
    print(p.subn(r'2 1', s))   # ('aaa test,bbb test', 2) (1 上方第一个括号内的内容。)
    print(p.subn(func, s))	# ('hei aaa,hei bbb', 2)
    print(p.subn(func, s, 1))	# ('hei aaa,test bbb', 1)
    

    一些注意点

    1、re.matchre.searchre.findall的区别:

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

    import re
    
    p = re.compile(r'[d]')
    s = 'abc33'
    print(p.search(s).group())	# 3
    print(p.match(s))	# None
    print(p.findall(s))	# ['3', '3']
    

    2、贪婪匹配与非贪婪匹配

    *,+,?等都是贪婪匹配,也就是尽可能多的匹配,后面加上?号使其变成

    惰性匹配。

    import re
    
    a = re.findall(r'a(d+?)', 'a23b')
    print(a)
    b = re.findall(r'a(d+)', 'a23b')
    print(b)
    

    注意:如果前后均有限定条件的时候,就不存在什么贪婪模式了,非匹配模式失效。

    import re
    
    a = re.findall(r'a(d+)b', 'a3333b')
    print(a)
    b = re.findall(r'a(d+?)b', 'a3333b')
    print(b)
    
  • 相关阅读:
    代码阅读之术一:结构与源流
    linux cat /etc/passwd 说明
    Linux软连接
    文件上传文件的权限--lnmp 环境配置,尤其整个项目复制过来
    Redis面试总结
    php上传文件与图片到七牛的实例详解
    在浏览器中打开php文件时,是Linux中的哪个用户执行的?
    Laravel [1045] 解决方法 Access denied for user 'homestead'@'localhost'
    linux中快速清空文件内容的几种方法
    linux如何查看所有的用户和组信息?
  • 原文地址:https://www.cnblogs.com/Monste/p/13456896.html
Copyright © 2011-2022 走看看