• 第十四天:正则表达式


    一、概述

    1、概念

    • Regular Expression
    • 一种文本模式,描述在搜索文本时要匹配的一个或多个字符串
      正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。

    2、典型场景

    • 数据验证
    • 文本扫描
    • 文本提取
    • 文本替换
    • 文本分割

    3、语法

    字面值

    普通字符

    需转义

         
         ^
        $
        .
        |
        ?
        *
        +
        ()
        []
        {}
    

    元字符

    4、匹配

    单字,预定义元字符

    • 除 外的所有字符 .
    • 数字,等同于[0-9] d
    • 非数字,等同于[^0-9] D
    • 空白字符 [ f v] s
    • 非空白字符 [^ f v] S
    • 字母数字字符 [a-z A-Z 0-9 _ ] w
    • 非字母数字字符 [^a-z A-Z 0-9 _ ] W

    批量备选 或( | ) , 如yes|no

    量词(控制 "字符、元字符,字符集" 如何重复)

    • 0或1次 ?
    • 0次或多次 *
    • 1次或多次 +
    • 特定
      • 范围次数{n,m}
      • n次{n}
      • 至少n次{n,}
      • 至多m次{,m}

    贪婪与非贪婪

    贪婪(默认):尽量匹配最大范围结果

    非贪婪:尽量匹配最小的范围结果

    • 方法:量词后追加?
    • 例子
      • ??
      • *?
      • +?

    边界匹配

    • 行首 ^
    • 行尾 $
    • 单词边界 
    • 非单词边界 B
    • 输入的开头 A
    • 输入的结尾 
    • 注:可能会由于上下文不同而有所差异

    二、Python 正则

    模块

    • import re

    RegexObject 正则对象

    1、模式对象,表现编译后的正则表达式(编译为字节码并缓存)

    2、编译

    • re.compile(r'模式')

    3、.findall()

    • 查找所有非重叠匹配项
    • 返回list
    import re
    text = "Tom is 8 years old. Mike is 34 years old."
    pattern = re.compile('d+') #数字,等同于[0-9]  d,1次或多次 +
    pattern.findall(text) #开发的方法
    re.findall('d+', text) #这种实现也可以,实际开发常用第一种,后面的参数是指明在哪寻找
    
    ['8', '34']
    ['8', '34']
    
    import re
    s = '\author:Tom'
    pattern = re.compile('\\author') #第一种查找有转义符的方式
    pattern.findall(s)
    pattern = re.compile(r'\author')#第二种查找转义符的方式
    pattern.findall(s)
    
    ['\author']
    ['\author']
    

    4、.match(string[,pos[,endpos]])

    • 匹配,仅从起始位置
    • 返回MatchObject
    import re
    text = 'Tom is 8 years old. Mike is 34 years old.Peter is 87 years old.'
    p_name = re.compile(r'[A-Z]w+') #字母数字字符 [a-z A-Z 0-9 _ ] w,1次或多次 +
    p_name.findall(text)
    
    ['Tom', 'Mike', 'Peter']
    
    import re
    pattern = re.compile(r'<html>')
    text = '<html><head></head><body></body></html>'
    pattern.match(text) #返回MatchObject对象
    text2 = ' <html><head></head><body></body></html>'
    pattern.match(text2, 1) #match只从开始的位置开始匹配,字符串前面有空格就不行,返回空,要设置了开始匹配的位置,就能顺利返回查找对象
    
    <re.Match object; span=(0, 6), match='<html>'>
    <re.Match object; span=(1, 7), match='<html>'>
    

    5、.search(string[,[pos[,endpos]]])

    • 任意位置搜索
    • 返回 MatchObject
    text2 = ' <html><head></head><body></body></html>'
    pattern.search(text2) #不管什么位置都能查找
    
    <re.Match object; span=(1, 7), match='<html>'>
    
    import re
    text = 'Tom is 8 years old. Mike is 34 years old.Peter is 87 years old.'
    p1 = re.compile(r'd+')
    p2 = re.compile(r'[A-Z]w+')
    it = p1.finditer(text)
    for m in it:
        print(m) #返回每个查找到对象的起始与终止,还有对象
    
    <re.Match object; span=(7, 8), match='8'>
    <re.Match object; span=(28, 30), match='34'>
    <re.Match object; span=(50, 52), match='87'>
    

    MatchObject 匹配对象

    1、表现被匹配的对象

    2、 .group()

    • 参数为0或空返回整个匹配
    • 有参时返回特定分组匹配细节
    • 参数也可以是分组名称
    import re
    text = 'Tom is 8 years old. Jerry is 34 years old.'
    pattern = re.compile(r'(d+).*?(d+)')
    m = pattern.search(text)
    m.group()
    m.group(1) #方法里面的参数,0表示整体,1表示第一个对象,2表示第二个对象
    
    '8 years old. Jerry is 34'
    '8'
    
    import re
    pattern = re.compile(r'(w+) (w+)') #注意中间有空格
    text = 'Beautiful is better than ugly.'
    it = pattern.finditer(text)
    for m in it:
        print(m.group())
    
    Beautiful is
    better than
    

    3、.groups()

    • 返回包含所有子分组的元组
    m.groups()
    
    ('8', '34')
    

    4、.start()

    • 返回特定分组的起始索引
    m.start(1) #返回找到的第一个对象在元字符串的索引下标
    
    7
    

    5、.end()

    • 返回特定分组的终止索引
    m.end(1) #返回查到的第一个对象终止的下标,在这里也就是数字8后面的空格的索引
    
    8
    

    6、.span()

    • 返回特定分组的起止索引元组

    7、.groupdict()

    • 以字典表形式返回分组名及结果

    Group 编组

    1、场景

    • 从匹配模式中提取信息
    • 创建子正则表达式以应用量词
    import re
    re.search(r'ab+c', 'ababc')
    re.search(r'(ab)+c', 'ababc')
    
    <re.Match object; span=(2, 5), match='abc'>
    <re.Match object; span=(0, 5), match='ababc'>
    
    • 限制备选项范围
    re.search(r'Center|re', 'Center')
    re.search(r'Center|re', 'Centre')
    re.search(r'Cent(er|re)', 'Centre')
    re.search(r'Cent(er|re)', 'Center')
    
    <re.Match object; span=(0, 6), match='Center'>
    <re.Match object; span=(4, 6), match='re'>
    <re.Match object; span=(0, 6), match='Centre'>
    <re.Match object; span=(0, 6), match='Center'>
    
    • 重用正则模式中提取的内容
    re.search(r'(w+) 1', 'hello hello worlds')
    import re
    text = "Tom:98"
    pattern = re.compile(r'(w+):(d+)')
    m = pattern.search(text)
    m.group()
    m.groups()
    m.group(1)
    
    'Tom:98'
    ('Tom', '98')
    'Tom'
    

    2、声明

    • (模式)
    • (?P模式)

    3、引用

    • 匹配对象内 m.group(‘name’)
    • 模式内 (?P=name)
    • 表现内 g
    pattern = re.compile(r'(?P<name>w+):(?P<score>d+)')
    m = pattern.search(text)
    m.group()
    m.group('name')
    m.group('score')
    
    'Tom:98'
    'Tom'
    '98'
    

    应用

    1、字符串操作

    • .split(string,maxsplit=0)
      分割字符串,使用编组不会删除分割内容
    import re
    text = 'Beautiful is better ugly.
    Explicit is better than implicit.
    Simple is better than complex.'
    p = re.compile(r'
    ')
    p.split(text)
    re.split(r'
    ', text, 1)
    
    ['Beautiful is better ugly.',
     'Explicit is better than implicit.',
     'Simple is better than complex.']
    ['Beautiful is better ugly.',
     'Explicit is better than implicit.
    Simple is better than complex.']
    
    • .sub(repl,string,count=0)
      替换字符串
    import re
    ords = 'ORD000
    ORD001
    ORD003'
    re.sub(r"d+",'-', ords)
    text = 'Beautiful is *better* ugly.'
    re.sub(r'*(.*?)*','<strong>g<1></strong>', text)
    re.sub(r'*(?P<html>.*?)*','<strong>g<html></strong>', text) #也可以使用这种方法
    re.sub(r'([A-Z]+)(d+)','g<2>-g<1>', ords)
    
    'ORD-
    ORD-
    ORD-'
    'Beautiful is <strong>better</strong> ugly.'
    'Beautiful is <strong>better</strong> ugly.'
    '000-ORD
    001-ORD
    003-ORD'
    
    • .subn(repl,string,count=0)
      替换并返回替换数量
    re.subn(r'([A-Z]+)(d+)','g<2>-g<1>', ords)
    
    ('000-ORD
    001-ORD
    003-ORD', 3)
    

    2、编译标记

    • 改变正则的默认行为
    • 忽略大小写 re.I
    import re
    text = 'Python python PYTHON'
    re.search(r'python', text)
    re.findall(r'python', text, re.I) #忽略大小写
    
    ['Python', 'python', 'PYTHON']
    
    • 忽略多行 re.M
    import re
    re.findall(r'^<html>', '
    <html>', re.M)
    
    ['<html>']
    
    • 指定“.”匹配所有字符包括 re.S
    re.findall(r'd(.)','1
    e',re.S)
    
    ['
    ']
    

    3、模块级别操作

    • 清理正则缓存 re.purge()
    • 逃逸字符 re.escape()
  • 相关阅读:
    FreeMarker MyEclipse IDE
    Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring
    Mybatis SqlSessionTemplate 源码解析
    Mybatis Interceptor 拦截器原理 源码分析
    MyBatis Mapper 接口如何通过JDK动态代理来包装SqlSession 源码分析
    MyEclipse SVN 下面切换用户的解决方案
    SpringMVC 多个数据源 配置多个事物管理器 Multiple Transaction Managers
    Activiti 获取定义
    [No000066]python各种类型转换-int,str,char,float,ord,hex,oct等
    [No000065]python 获取当前时间
  • 原文地址:https://www.cnblogs.com/linyk/p/11486193.html
Copyright © 2020-2023  润新知