zoukankan      html  css  js  c++  java
  • Python-正则表达式

    python正则表达式

    re模块提供正则表达式操作

    re模块中常用方法:

    • match

    • search

    • findall

    • finditer

    • sub

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

    根据正则表达式pattern, 从待匹配字符串string的开头进行匹配, 如果匹配成功, 则返回正则匹配结果对象; 如果没有匹配成功, 返回None.

    import re
    ​
    s1 = 'hello kitty'
    s2 = 'kitty hello'
    r1 = re.match('hello', s1)
    print(r1)
    print(r1.group())
    r2 = re.match('hello', s2)
    print(r2)
    ​
    # 执行结果
    <_sre.SRE_Match object; span=(0, 5), match='hello'>  # 这是正则匹配结果对象,不是具体的匹配值
    hello
    None
    # 得到正则匹配结果对象, 可以调用正则匹配结果对象的方法或属性

    调用正则匹配结果对象(match object)group方法, group参数说明

    s1 = 'hello kitty haha kitty'
    pattern = re.compile('(hello).*?(haha)')
    r = re.match(pattern, s1)
    print(r)
    print(r.group()) # group中没有参数,就是默认为0,与r1.gruop(0)等价; 返回整个match的匹配结果
    print(r.group(1)) # 字符串形式返回匹配的第一个括号组(子组)
    print(r.group(2)) # 字符串形式返回匹配的第二个括号组
    print(r.groups()) # 返回所有的匹配括号组, 放在一个元组中返回
    # 执行结果
    <_sre.SRE_Match object; span=(0, 16), match='hello kitty haha'>
    hello kitty haha
    hello
    haha
    ('hello', 'haha')

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

    顺序扫描 string , 寻找正则表达式 pattern 产生匹配的第一个位置, 并返回相应的正则匹配结果对象; 若string中没有任何位置能匹配该模式, 则返回 None.

    s = 'this123long456str'
    pattern = re.compile('d+')
    r = re.search(pattern, s)
    print(r)
    print(r.group())
    ​
    # 执行结果
    <_sre.SRE_Match object; span=(4, 7), match='123'>  # 找到符合正则表达式规则的字符串后,返回结果
    123  # 找到符合规则后,不在继续向后查找匹配,所以后面符合规则的456不会返回
    s = 'this123long456str'
    pattern = re.compile('w+?(d+)w+?(d+).*')
    r = re.search(pattern, s)
    print(r)
    print(r.group())
    print(r.group(1))
    print(r.group(2))
    print(r.groups())
    ​
    # 执行结果
    <_sre.SRE_Match object; span=(0, 17), match='this123long456str'>
    this123long456str
    123
    456
    ('123', '456')

    re.findall(pattern, string, flags)

    返回字符串pattern的所有非重叠匹配项作为字符串列表. The string是从左到右扫描的, 所以匹配的内容是按照该顺序来的, 如果模式中存在一个或多个组,请返回组列表; 如果模式有多个组, 这将是一个元组列表。

    说明:

    • 如果pattern中不包含分组, 那么按照pattern从左到右扫描string, 符合pattern规则的, 提取出来, 加到列表中, 继续向右扫描, 遇到符合pattern规则的再加到列表中. 返回结果就是一个大的列表, 如果没有找到匹配, 则返回空列表.

    • 如果pattern中包含分组, 且只有一个分组, 那么按照pattern规则匹配, 但是会把分组的匹配结果加到列表中,不是把符合pattern这个整体规则的结果加到列表中.

    • 如果pattern中包含分组, 且有多个分组, 那么按照patter规则匹配, 匹配成功后, 会把每个分组的匹配结果提出来组成一个元组, 然后把这个元组加到列表中, 最终结果就是多个元组组成的列表.

    # 1)不包含分组
    s = 'abc 123cd 56ef'
    pattern = re.compile('d+w+')
    r = re.findall(pattern, s)
    print(r)
    # 执行结果
    ['123cd', '56ef']
    ​
    # 2)包含一个分组
    s = 'abc 123cd 56ef'
    pattern = re.compile('d+(w+)')
    r = re.findall(pattern, s)
    print(r)
    # 执行结果
    ['cd', 'ef']
    ​
    # 3)包含多个分组
    s = 'abc 123cd 56ef'
    pattern = re.compile('(d+)(w+)')
    r = re.findall(pattern, s)
    print(r)
    # 执行结果
    [('123', 'cd'), ('56', 'ef')]

    re.finditer(pattern, string, flags)

    finditer与findall类似, 但是finditer的返回结果是一个迭代器

    # 1)不包含分组
    s = 'abc 123cd 56ef'
    pattern = re.compile('d+w+')
    r = re.finditer(pattern, s)
    print('type result:', type(r))
    for item in r:
        print(item)
        print(item.group())
    # 执行结果
    type result: <class 'callable_iterator'>
    <_sre.SRE_Match object; span=(4, 9), match='123cd'>
    123cd
    <_sre.SRE_Match object; span=(10, 14), match='56ef'>
    56ef
    ​
    # 2)包含一个分组
    s = 'abc 123cd 56ef'
    pattern = re.compile('d+(w+)')
    r = re.finditer(pattern, s)
    for item in r:
        print(item.group())
        print(item.group(1))
    # 执行结果
    123cd
    cd
    56ef
    ef
    ​
    # 3)包含两个分组
    pattern = re.compile('(d+)(w+)')
    r = re.finditer(pattern, s)
    for item in r:
        print(item.group())
        print(item.group(1))
        print(item.group(2))
    # 执行结果
    123cd
    123
    cd
    56ef
    56
    ef

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

    string中最左侧非重叠出现的pattern替换为repl, 返回所获得的字符串.

    s = 'abc123efg45hh'
    pattern = re.compile('d+')
    r = re.sub(pattern, '-', s)
    print(r)
    # 执行结果
    abc-efg-hh
    ​
    # 可以指定替换次数
    s = 'abc123efg45hh'
    pattern = re.compile('d+')
    r = re.sub(pattern, '-', s, count=1)
    print(r)
    # 执行结果
    abc-efg45hh

    其他正则表达式语法

    (?:...)

    一个正则括号的不捕获版本. 如果pattern中包含分组, 那么pattern整体匹配后, 会把分组的匹配值作为结果返回, 就是分组的优先级高. 如果我只是想把分组当做普通的分组处理, 不把它的匹配值作为结果返回, 而是返回pattern整体匹配值的结果, 那么就可以在分组内部加上?:

    s = 'abc123efg45hh'
    pattern = re.compile('w+?d+')
    r = re.findall(pattern, s)
    print(r)
    # 执行结果
    ['abc123', 'efg45']
    ​
    s = 'abc123efg45hh'
    pattern = re.compile('w+?(d+)')
    r = re.findall(pattern, s)
    print(r)
    # 执行结果
    ['123', '45']  # 优先返回分组结果
    ​
    s = 'abc123efg45hh'
    pattern = re.compile('w+?(?:d+)')
    r = re.findall(pattern, s)
    print(r)
    # 执行结果
    ['abc123', 'efg45']  # 把pattern内的分组当做普通分组处理, 返回pattern整体匹配值

    (?P<name>...)

    和正则括号相似, 但是这个组匹配到的子字符串可以通过符号组名称name进行访问.组名称必须是有效的Python标识符, 并且每个组名称在正则表达式中只能被定义一次(注:组名必须唯一).一个符号组也是一个带编号的组, 就好像这个组没有被命名一样.(注:除了原有的编号外再指定一个额外的别名).

    s = '<a>This is a link</a>'
    pattern = re.compile('<(?P<tag1>w+)>.*?<(?P<tag2>/w+)>')
    r = re.search(pattern, s)
    print(r)
    print(r.group())
    print(r.group(1))
    print(r.group(2))
    print(r.group('tag1'))
    print(r.group('tag2'))
    # 执行结果  # 就是为分组指定了名称,可以根据名称去访问这个组的匹配值
    <_sre.SRE_Match object; span=(0, 21), match='<a>This is a link</a>'>
    <a>This is a link</a>
    a
    /a
    a
    /a

    (?P=name)

    对指定组的反向引用;它匹配任何名为name的早期组匹配的文本。

    s = '<a>This is a link</a>'
    pattern = re.compile('<(?P<tag1>w+)>.*?</(?P=tag1)>')  
    # ?P=tag1中匹配的内容必须与之前组名tag1匹配的完全一致
    r = re.search(pattern, s)
    print(r)
    print(r.group())
    print(r.group('tag1'))
    # 执行结果
    <_sre.SRE_Match object; span=(0, 21), match='<a>This is a link</a>'>
    <a>This is a link</a>
    a

    以上就是关于python re模块常用方法的总结, 欢迎补充.

     

  • 相关阅读:
    HNOI 2006 BZOJ 1195 最短母串
    BZOJ 3029 守卫者的挑战
    Codeforces 401D Roman and Numbers
    ZJOI2010 数字计数
    BZOJ 3329 Xorequ
    Codeforces 235 C
    SPOJ 8222 Substrings
    BZOJ 1396 识别子串
    (模板)归并排序
    poj3122 Pie (二分)
  • 原文地址:https://www.cnblogs.com/gandoufu/p/9457386.html
Copyright © 2011-2022 走看看