• Python正则表达式


    Python正则表达式

    1.正则表达式字符串是由普通字符和元字符表示。

    ①元字符 ②普通字符

    基本元字符
    字符 说明
    转义符,表示转义
    . 表示任意一个字符
    + 表示重复一次或多次
    * 表示重复零次或多次
    ? 表示重复零次或一次
    | 选择符号,表示“或关系“,例如:A|B表示匹配A或B
    { } 定义量词
    [ ] 定义字符类
    ( ) 定义分组
    ^ 可以表示取反,或匹配一行的开始
    $ 匹配一行的结束

    当以^开始时,要求一行字符串的开始位置匹配;当以$结束时,要求一行字符串的结束位置匹配。所以正则表达式w+@zhi jieketang.com和^w+@zhi jieketang.com$是不同的。

    import re
    
    p1=r'w+@zhijieketang.com'
    p2=r'^w+@zhijieketang.com$'
    
    text = "Tony's email is tony_guan588@zhijieketang.com."
    m = re.search(p1,text)
    print(m)
    
    m = re.search(p2,text)
    print(m)
    
    email = 'tony_guan588@zhijieketang.com'
    m = re.search(p2,email)
    print(m)
    

    函数

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

    import re 
    print(re.match('www', 'www.runoob.com').span())  # 在起始位置匹配 
    print(re.match('com', 'www.runoob.com'))         # 不在起始位置匹配
    #输出结果
    (0,3)
    None
    

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

    import re
    print(re.search('www', 'www.runoob.com').span())  # 在起始位置匹配
    print(re.search('com', 'www.runoob.com').span())         # 不在起始位置匹配
    #输出结果
    (0, 3)
    (11, 14)
    

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

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

    import re
     
    pattern = re.compile(r'd+')   # 查找数字
    result1 = pattern.findall('runoob 123 google 456')
    result2 = pattern.findall('run88oob123google456', 0, 10)
     
    print(result1)
    print(result2)
    #输出结果
    ['123', '456']
    ['88', '12']
    

    re.finditer和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。

    import re
     
    it = re.finditer(r"d+","12a32bc43jf3") 
    for match in it: 
        print (match.group() )
     # 输出结果
    12 
    32 
    43 
    3
    

    split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:

    re.split(pattern, string[, maxsplit=0, flags=0])
    

    pattern:匹配的正则表达式

    string:要匹配的字符串。

    maxsplit:分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。

    flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

    import re
    p = r'd+'
    text = 'AB12CD34EF'
    clist = re.split(p,text)
    print(clist)
    clist = re.split(p,text,maxsplit=1)  #最大分隔一次
    print(clist)
    clist = re.split(p,text,,maxsplit=2)  #最大分隔两次
    print(clist)
    #输出结果
    ['AB','CD','EF']
    ['AB','CD34EF']
    ['AB','CD','EF']
    

    re.sub用于替换字符串中的匹配项。

    re.sub(pattern, repl, string, count=0, flags=0)
    
    • pattern : 正则中的模式字符串。
    • repl : 替换的字符串,也可为一个函数。
    • string : 要被查找替换的原始字符串。
    • count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
    import re
    p = r'd+'
    text = 'AB12CD34EF'
    repace_text = re.sub(p,'',text)
    print(repace_text)
    #输出结果
    ABCDEF
    

    compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。编译的正则表达式可以重复使用,减少正则表达式解析和验证,提高效率。

    re.compile(pattern[, flags])
    
    • pattern : 一个字符串形式的正则表达式
    • flags : 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:
      1. re.I 忽略大小写
      2. re.L 表示特殊字符集 w, W, , B, s, S 依赖于当前环境
      3. re.M 多行模式
      4. re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符)
      5. re.U 表示特殊字符集 w, W, , B, d, D, s, S 依赖于 Unicode 字符属性数据库
      6. re.X 为了增加可读性,忽略空格和 # 后面的注释
    >>>import re
    >>> pattern = re.compile(r'd+')                    # 用于匹配至少一个数字
    >>> m = pattern.match('one12twothree34four')        # 查找头部,没有匹配
    >>> print m
    None
    >>> m = pattern.match('one12twothree34four', 2, 10) # 从'e'的位置开始匹配,没有匹配
    >>> print m
    None
    >>> m = pattern.match('one12twothree34four', 3, 10) # 从'1'的位置开始匹配,正好匹配
    >>> print m                                         # 返回一个 Match 对象
    <_sre.SRE_Match object at 0x10a42aac0>
    >>> m.group(0)   # 可省略 0
    '12'
    >>> m.start(0)   # 可省略 0
    3
    >>> m.end(0)     # 可省略 0
    5
    >>> m.span(0)    # 可省略 0
    (3, 5)
    

    字符类

    正则表达式中可以使用字符类,一个字符类定义一组字符,其中的任一字符出现在输出字符串中即匹配成功。注意每次匹配只能匹配字符类中的一个字符。

    1.定义字符类

    定义一个普通的字符类需要使用'['和']'元字符类。

    import re
    # 在输入字符串中匹配Java或java,可以使用正则表达式[Jj]ava。
    p = r'[Jj]ava
    m = re.search(p,'I like Java and Python')
    print(m)
    m = re.search(p,'I like JAVA and Python')
    print(m)
    m = re.search(p,'I like java and Python')
    print(m)
    

    2.字符类取反

    有时需要在正则表达式中指定不想出现的字符,可以在字符类前加"^"符号。

    import re
    #表示非数字
    p = r'[^0123456789]''
    m = re.search(p,'1000')
    print(m)
    m = re.search(p,'Python 3')
    print(m)
    #遇到第一个匹配的就返回
    

    3.区间

    区间是用连字符(-)表示的,[0123456789]采用区间表示[0-9],[^0123456789]采用区间表示[^0-9]。[A-Za-z0-9]表示任何字母和数值字符类,[0-25-7]表示0、1、2、5、6、7几个字符组成的字符类。

    import re 
    m = re.search(r'[A-Za-z0-9]'','A10.3')
    print(m)
    m = re.search(r'[0-25-7],'A34879C')
    print(m)
    #输出结果
    <_sre.SRE_Match object;span=(0,1),match='A'>
    <_sre.SRE_Match object;span=(4,5),match='7'>
    

    4.预定义字符类

    字符 说明
    . 匹配任意一个字符
    \ 匹配反斜杠字符
    匹配换行
    匹配回车
    f 匹配一个换页符
    匹配一个水平制表符
    v 匹配一个垂直制表符
    s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ f v]。
    S 匹配任何非空白字符。等价于 [^ f v]。
    d 匹配一个数字字符。等价于 [0-9]。
    D 匹配一个非数字字符。等价于 [^0-9]。
    w 匹配任何语音的单词字符(如:英文字母、亚洲文字等)、数字和下划线(_)等字符。如果正则表达式编译标志设置为ASCII,则只匹配'[A-Za-z0-9_]'。
    W 等价于 '[^w]'。

    量词

    表示字符或字符串重复的次数。

    字符 说明
    出现零次或一次
    * 出现零次或多次
    + 出现一次或多次
    {n} 出现零次或n次
    {n,m} 至少出现n次但不超过m次
    {n,} 至少出现n次

    贪婪量词会尽可能多地匹配字符;懒惰量词尽可能少地匹配字符。大多数计算机语言的正则表达式量词默认是贪婪的,要想使用懒惰量词可以在量词后面加“?”即可。

    import re
    # 使用贪婪量词
    m = re.search(r'd{5,8}','87654321')     #出现数字8次
    print(m)  #匹配字符'87654321'
    # 使用惰性量词
    m = re.search(r'd{5,8}?','87654321')     #出现数字5次
    print(m)  #匹配字符'87654'
    #输出结果
    <_sre.SRE_Match object;span=(0,8),match='87654321'>
    <_sre.SRE_Match object;span=(0,5),match='87654'>
    

    分组

    如果想让一个字符串作为整体使用量词,可将这个字符串放到一对小括号中,这就是分组。

    import re 
    p = r'(121){2}''
    m = re.search(p,'121121abcabc')
    print(m)
    print(m.group())   #返回匹配的字符串
    print(m.groups())  #返回所有组的内容
    
    p = r'(d{3,4})-(d{7,8})'
    m = re.search(p,'010-87654321')
    print(m)
    print(m.group())   #返回匹配的字符串
    print(m.groups())
    # 输出结果
    <_sre.SRE_Match object;span=(0,6),match='121121'>
    121121
    ('121',)
    <_sre.SRE_Match object;span=(0,12),match='010-87654321'>
    010-87654321
    ('010','87654321')
    

    1.对正则表达式进行分组不仅可以对一个字符串整体使用量词,还可以在正则表达式中引用已经存在的分组。

    2.在Python程序中访问分组时,除了可以通过组编号进行访问,还可以通过组名进行访问,前提是要在正则表达式中为组命名。组命名语法是在分组的左小括号后添加?P<分组名>实现。

    3.反向引用分组。除了可以在程序代码中访问正则表达式匹配之后的分组内容,还可以在正则表达式内部引用之前的分组。

    import re
    p = r'<([w]+)>.*</1>'
    m = re.search(p,'<a>abc</a>')
    print(m)
    m = re.search(p,'<a>abc</b>')
    print(m)
    # 输出结果
    <_sre.SRE_Match object;span=(0,10),match='<a>abc</a>'>
    None
    

    4.非捕获分组

    前面介绍的分组称为捕获分组,就是匹配子表达式结果被暂时保存到内存中,以被表达式或其他程序引用,这称之为“捕获”,捕获结果可以通过组编号或组名进行引用。但是有时并不想引用子表达式的匹配结果,不想捕获匹配结果,只是将小括号作为一个整体进行匹配,此时可以使用非捕获分组,非捕获分组在组开头使用“?:"实现。

    import re
    s = 'img1.jpg,img2.jpg,img3.bmp'
    p = r'w+(.jpg)'
    m = re.findall(p,s)
    print(m)
    p = r'w+(?:.jpg)'
    m = re.findall(p,s)
    print(m)
    #输出结果
    ['.jpg','.jpg']
    ['img1.jpg','img2.jpg']
    
  • 相关阅读:
    Java性能小技巧
    使用Gitolite搭建Gitserver
    refresh的停车场(栈和队列的STL)
    BZOJ 2005 NOI2010 能量採集 数论+容斥原理
    PHP第四课 了解经常使用的函数
    JavaScript实现对象数组按不同字段排序
    android之Context对各种服务的管理
    程序员应该阅读的非编程类书籍有哪些?
    是男人就下100层【第五层】——换肤版2048游戏
    是男人就下100层【第四层】——Crazy贪吃蛇(3)
  • 原文地址:https://www.cnblogs.com/levelstrcpy/p/14303488.html
Copyright © 2020-2023  润新知