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

    re模块

      正则表达式本身是一种小型的、高度专业化的编程语言,而在python中,通过内嵌集成re模块,程序媛们可以直接调用来实现正则匹配。正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎执行。

    正则表达式中常用的字符含义

    1、普通字符和11个元字符:

    普通字符
    匹配自身
    abc
    abc
    .
    匹配任意除换行符" "外的字符(在DOTALL模式中也能匹配换行符
    a.c
    abc
    转义字符,使后一个字符改变原来的意思
    a.c;a\c
    a.c;ac
    *
    匹配前一个字符0或多次
    abc*
    ab;abccc
    +
    匹配前一个字符1次或无限次
    abc+
    abc;abccc
    ?
    匹配一个字符0次或1次
    abc?
    ab;abc
    ^
    匹配字符串开头。在多行模式中匹配每一行的开头 ^abc
    abc
    $
    匹配字符串末尾,在多行模式中匹配每一行的末尾 abc$
    abc
    | 或。匹配|左右表达式任意一个,从左到右匹配,如果|没有包括在()中,则它的范围是整个正则表达式
    abc|def
    abc
    def
    {} {m}匹配前一个字符m次,{m,n}匹配前一个字符m至n次,若省略n,则匹配m至无限次
    ab{1,2}c
    abc
    abbc
    []
    字符集。对应的位置可以是字符集中任意字符。字符集中的字符可以逐个列出,也可以给出范围,如[abc]或[a-c]。[^abc]表示取反,即非abc。
    所有特殊字符在字符集中都失去其原有的特殊含义。用反斜杠转义恢复特殊字符的特殊含义。
    a[bcd]e
    abe
    ace
    ade
     
    ()
    被括起来的表达式将作为分组,从表达式左边开始没遇到一个分组的左括号“(”,编号+1.
    分组表达式作为一个整体,可以后接数量词。表达式中的|仅在该组中有效。
    (abc){2}
    a(123|456)c
    abcabc
    a456c

    这里需要强调一下反斜杠的作用:

    • 反斜杠后边跟元字符去除特殊功能;(即将特殊字符转义成普通字符)
    • 反斜杠后边跟普通字符实现特殊功能;(即预定义字符)
    • 引用序号对应的字组所匹配的字符串。
    a=re.search(r'(tina)(fei)haha2','tinafeihahafei tinafeihahatina').group()
    print(a)
    结果:
    tinafeihahafei

    2、预定义字符集(可以写在字符集[...]中) 

    d
    数字:[0-9]
    ac
    a1c
    D
    非数字:[^d]
    aDc
    abc
    s
    匹配任何空白字符:[<空格> fv]
    asc
    a c
    S 非空白字符:[^s]
    aSc
    abc
    w
    匹配包括下划线在内的任何字字符:[A-Za-z0-9_]
    awc
    abc
    W
    匹配非字母字符,即匹配特殊字符
    aWc
    a c
    A
    仅匹配字符串开头,同^ Aabc
    abc
    
    仅匹配字符串结尾,同$
    abc
    abc
    
    匹配w和W之间,即匹配单词边界匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 abc
    a!bc
    空格abc空格
    a!bc
    B
    [^]
    aBbc
    abc
    复制代码
    这里需要强调一下的单词边界的理解:
    w = re.findall('tina','tian tinaaaa') print(w) s = re.findall(r'tina','tian tinaaaa') print(s) v = re.findall(r'tina','tian#tinaaaa') print(v) a = re.findall(r'tina','tian#tina@aaa') print(a) 执行结果如下: [] ['tina'] ['tina'] ['tina']
    复制代码

    3、特殊分组用法:

    (?P<name>)
    分组,除了原有的编号外再指定一个额外的别名 (?P<id>abc){2}
    abcabc
    (?P=name)
    引用别名为<name>的分组匹配到字符串 (?P<id>d)abc(?P=id)
    1abc1
    5abc5
    <number>
    引用编号为<number>的分组匹配到字符串 (d)abc1
    1abc1
    5abc5

    4、贪婪匹配与非贪婪匹配

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

    a = re.findall(r"a(d+?)",'a23b')
    print(a)
    b = re.findall(r"a(d+)",'a23b')
    print(b)
    执行结果:
    ['2']
    ['23']
    
    
    a = re.match('<(.*)>','<H1>title<H1>').group()
    print(a)
    b = re.match('<(.*?)>','<H1>title<H1>').group()
    print(b)
    执行结果:
    <H1>title<H1>
    <H1>
    
    a = re.findall(r"a(d+)b",'a3333b')
    print(a)
    b = re.findall(r"a(d+?)b",'a3333b')
    print(b)
    执行结果如下:
    ['3333']
    ['3333']
    #######################
    这里需要注意的是如果前后均有限定条件的时候,就不存在什么贪婪模式了,非匹配模式失效。
    View Code

     

    re模块中常用功能函数

    compile

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

    格式:

    re.compile(pattern,flags=0)

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

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

    标志
    含义
    re.S(DOTALL)
    使.匹配包括换行在内的所有字符
    re.I(IGNORECASE)
    忽略大小写
    re.L(LOCALE)
    使预定字符类 w W  B s S 取决于当前区域设定 
    re.M(MULTILINE)
    多行匹配,改变'^'和'$'的行为 
    re.X(VERBOSE)
    详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释 
    re.U
    使预定字符类 w W  B s S d D 取决于unicode定义的字符属性
    复制代码
    import re
    tt = "Tina is a good girl, she is cool, clever, and so on..."
    rr = re.compile(r'w*oow*')
    print(rr.findall(tt))   #查找所有包含'oo'的单词
    执行结果如下:
    ['good', 'cool']
    复制代码

    match

    # match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None
     
     
     match(pattern, string, flags=0)
     # pattern: 正则模型
     # string : 要匹配的字符串
     # falgs  : 匹配模式
         X  VERBOSE     Ignore whitespace and comments for nicer looking RE's.
         I  IGNORECASE  Perform case-insensitive matching.
         M  MULTILINE   "^" matches the beginning of lines (after a newline)
                        as well as the string.
                        "$" matches the end of lines (before a newline) as well
                        as the end of the string.
         S  DOTALL      "." matches any character at all, including the newline.
     
         A  ASCII       For string patterns, make w, W, , B, d, D
                        match the corresponding ASCII character categories
                        (rather than the whole Unicode categories, which is the
                        default).
                        For bytes patterns, this flag is the only available
                        behaviour and needn't be specified.
          
         L  LOCALE      Make w, W, , B, dependent on the current locale.
         U  UNICODE     For compatibility only. Ignored for string patterns (it
                        is the default), and forbidden for bytes patterns.
    # 无分组
            r = re.match("hw+", origin)
            print(r.group())     # 获取匹配到的所有结果
            print(r.groups())    # 获取模型中匹配到的分组结果
            print(r.groupdict()) # 获取模型中匹配到的分组结果
    
            # 有分组
    
            # 为何要有分组?提取匹配成功的指定内容(先匹配成功全部正则,再匹配成功的局部内容提取出来)
    
            r = re.match("h(w+).*(?P<name>d)$", origin)
            print(r.group())     # 获取匹配到的所有结果
            print(r.groups())    # 获取模型中匹配到的分组结果
            print(r.groupdict()) # 获取模型中匹配到的分组中所有执行了key的组
    Demo

    search

    # search,浏览整个字符串去匹配第一个,未匹配成功返回None
    # search(pattern, string, flags=0)
    # 无分组
    
            r = re.search("aw+", origin)
            print(r.group())     # 获取匹配到的所有结果
            print(r.groups())    # 获取模型中匹配到的分组结果
            print(r.groupdict()) # 获取模型中匹配到的分组结果
    
            # 有分组
    
            r = re.search("a(w+).*(?P<name>d)$", origin)
            print(r.group())     # 获取匹配到的所有结果
            print(r.groups())    # 获取模型中匹配到的分组结果
            print(r.groupdict()) # 获取模型中匹配到的分组中所有执行了key的组
    
    demo
    Demo

    findall

    # findall,获取非重复的匹配列表;如果有一个组则以列表形式返回,且每一个匹配均是字符串;如果模型中有多个组,则以列表形式返回,且每一个匹配均是元祖;
    # 空的匹配也会包含在结果中
    #findall(pattern, string, flags=0)
    # 无分组
            r = re.findall("aw+",origin)
            print(r)
    
            # 有分组
            origin = "hello alex bcd abcd lge acd 19"
            r = re.findall("a((w*)c)(d)", origin)
            print(r)
    
    Demo
    Demo

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

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

    a=re.search('[d]',"abc33").group()
    print(a)
    p=re.match('[d]',"abc33")
    print(p)
    b=re.findall('[d]',"abc33")
    print(b)
    执行结果:
    3
    None
    ['3', '3']

    finditer

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

    格式:

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

    iter = re.finditer(r'd+','12 drumm44ers drumming, 11 ... 10 ...')
    for i in iter:
        print(i)
        print(i.group())
        print(i.span())
    执行结果如下:
    <_sre.SRE_Match object; span=(0, 2), match='12'>
    (0, 2)
    <_sre.SRE_Match object; span=(8, 10), match='44'>
    (8, 10)
    <_sre.SRE_Match object; span=(24, 26), match='11'>
    (24, 26)
    <_sre.SRE_Match object; span=(31, 33), match='10'>
    (31, 33)
    View Code

    sub

    # sub,替换匹配成功的指定位置字符串
     
    sub(pattern, repl, string, count=0, flags=0)
    # pattern: 正则模型
    # repl   : 要替换的字符串或可执行对象
    # string : 要匹配的字符串
    # count  : 指定匹配个数
    # flags  : 匹配模式
    # 与分组无关
    
            origin = "hello alex bcd alex lge alex acd 19"
            r = re.sub("aw+", "999", origin, 2)
            print(r)
    Demo

    subn

    返回替换次数

    格式:

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

    print(re.subn('[1-2]','A','123456abcdef'))
    print(re.sub("g.t","have",'I get A,  I got B ,I gut C'))
    print(re.subn("g.t","have",'I get A,  I got B ,I gut C'))
    执行结果如下:
    ('AA3456abcdef', 2)
    I have A,  I have B ,I have C
    ('I have A,  I have B ,I have C', 3)
    View Code

    split

    # split,根据正则匹配分割字符串
     
    split(pattern, string, maxsplit=0, flags=0)
    # pattern: 正则模型
    # string : 要匹配的字符串
    # maxsplit:指定分割个数
    # flags  : 匹配模式
    # 无分组
            origin = "hello alex bcd alex lge alex acd 19"
            r = re.split("alex", origin, 1)
            print(r)
    
            # 有分组
            
            origin = "hello alex bcd alex lge alex acd 19"
            r1 = re.split("(alex)", origin, 1)
            print(r1)
            r2 = re.split("(al(ex))", origin, 1)
            print(r2)
    
    Demo
    Demo

    escape

    把string中,除了字母和数字以外的字符,都加上反斜杆。

    >>> print(re.escape('abc123_@#$'))
    abc123_@#$
    IP:
    ^(25[0-5]|2[0-4]d|[0-1]?d?d)(.(25[0-5]|2[0-4]d|[0-1]?d?d)){3}$
    手机号:
    ^1[3|4|5|8][0-9]d{8}$
    邮箱:
    [a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+
    常用正则表达式
  • 相关阅读:
    Java实现 蓝桥杯 算法提高 小X的购物计划
    Java实现 蓝桥杯 算法提高 小X的购物计划
    Java实现 第十一届 蓝桥杯 (高职专科组)省内模拟赛
    Java实现 第十一届 蓝桥杯 (高职专科组)省内模拟赛
    Java实现 第十一届 蓝桥杯 (高职专科组)省内模拟赛
    Java 第十一届 蓝桥杯 省模拟赛 小明的城堡
    Java 第十一届 蓝桥杯 省模拟赛 小明的城堡
    Java 第十一届 蓝桥杯 省模拟赛 小明的城堡
    129. Sum Root to Leaf Numbers
    117. Populating Next Right Pointers in Each Node II
  • 原文地址:https://www.cnblogs.com/freely/p/6411549.html
Copyright © 2011-2022 走看看