zoukankan      html  css  js  c++  java
  • Python 正则处理_re模块

    正则表达式

    动机

    • 文本处理成为计算机常见工作之一
    • 对文本内容搜索,定位,提取是逻辑比较复杂的工作
    • 为了快速方便的解决上述问题,产生了正则表达式技术

    定义

    文本的高级匹配模式, 提供搜索, 替换, 本质由字符和特殊符号构成的字符串,

    这个字符串即为正则表达式

    匹配原理

    通过普通字符和特殊含义的字符串, 来组成字符串,

    用以描述一定的字符串规则, 比如重复, 位置, 来表达一种特定类型的字符串, 进而匹配

    正则字符

    通用

     0 - 9   匹配所有字符
     a - z   匹配所有小写字母
     A - Z   匹配所有大写字母
     A-Za-z  匹配所有字母

    字符

    .       换行符以外的任意
    w      数字, 字母, 下划线, 汉字    [a-z]
    s      空格
    d      数字  [0-9]
          单词边界    (数字,字母,下划线,汉字 与 其他字符交界位置)
    W      非 数字, 字母, 下划线, 汉字   [^a-z]
    S      非 空格
    D      非 数字    [^0-9]
    B      非 单词边界
    
          换行符
    	      制表符
    ^       开始位置
    $       结束位置
    |       或 (匹配上即不在匹配,需要 长的放在前面 例如 abc|ab )

    量词

    *       0~n次+       1~n次
    ?       0~1次
    {n}     n次
    {n,}    n或 n+次
    {n,m}   n~m 次

    字符集

    []      匹配字符组中的字符
    [^]     匹配除了字符中的所有字符

    分组

    ()      对整体进行 量词约束   ---> 1 2 3 进行位置选择
    (?:)    取消分组优先
    
    (?P<name>pattern)      命名分组   ----> g<name1> g<name2> 进行命名选择

    注意点

    • 一个正则中可以存在多个分组, 且分组可以嵌套
    • 作用前提是整体的表达式能被匹配到内容才可以
    • 未命名分组和命名分组是可以同时存在的, 未命名分组按照从外到内, 从左到右按照位置来用索引来命名
    • 分组不要重叠, 且最好不要嵌套, 倘若出现说明设计存在巨大缺陷

    转义

           被转义前加反斜线表示 匹配这一字符而不是用作正则表达式来处理
    r''     python 对字符串的不转义需要 用 r 来表示, 减去书写的麻烦

     实例解析

    # r""
    # s = "\hello"
    # print(re.findall("\\\w+", s))
    # print(re.findall(r'\w+', s))
    
    """
    python 字符串      --> 正则      --> 目标字符串
    "\$\d+"           $d+           "$100"
    r"$d+"            $d+           "$100"
    * 为避免特殊字符串在字符串中使用时转义的麻烦, 使用 raw 字符串来表达正则表达式
    """

    总结

    匹配单个字符

    . [] [^] d D w W s S

    匹配重复

    * + ? {n} {n,m}

    匹配位置

    ^ $ A   B

    其他

    | () 

    贪婪 / 非贪婪匹配

    • 默认 贪婪匹配 , 尽可能的往后匹配更多的内容
    • 加 ? 改为 非贪婪匹配, 懒惰模式, 满足条件后不往后匹配更多内容
    • 主要影响到的是重复匹配的操作符 * + ? {n} {n,m}
    # 非贪婪匹配的运用
    # s = "ashb, asjdlab, asdadb"
    # print(re.findall(r"a.*b", s))   # ['ashb, asjdlab,asdadb']
    # print(re.findall(r"a.*?b", s))  # ['ashb', 'asjdlab', 'asdadb']

    匹配原则

    • 正确性     正确的匹配出目标字符串
    • 精准性     除了目标内容, 尽可能不要存在多余内容
    • 全面性     尽可能对目标字符串考虑全面, 做到不遗漏

    Python re模块使用

    compile

    regex = compile(pattern,flags=0)

    功能  生成正则表达式对象

    参数

       pattern 正则表达式

      flags 功能标识,扩展正则匹配功能

    返回值  正则对象

    compile对象属性

    • flags : flags值
    • pattern : 正则表达式
    • groups : 子组数量
    • groupindex : 捕获组名与组序号的字典

    findall

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

    功能  通过正则表达式匹配目标字符串内容

    参数

      pattern 正则表达式

      string 目标字符串

    返回值  

       返回匹配到的内容列表

        如果正则表达式存在 子组 则只返回 子组对应的内容

    sub

    re.sub(pattern,replace,string,max,flags=0)

    功能  使用指定字符串替换正则表达式匹配内容

    参数  

      pattern 正则

      replace 指定字符串

      string 目标字符串

      max 最多替换几处,默认全部替换

    返回值  替换后的字符串

    subn

    re.subn() 

    功能参数 同sub,

    返回值 多一个实际替换个数

    finditer

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

    功能  使用正则表达式匹配目标内容

    参数  

      pattern 正则

      string 目标字符串

    返回值   迭代对象

    fullmatch

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

    功能  完全匹配某个目标字符串

    参数  

      pattern 正则

      string 目标字符串

    返回值  匹配内容match object

    match

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

    功能  匹配某个目标字符串开始位置

    参数

      pattern 正则

      string 目标字符串

    返回值  匹配内容match object

    match 对象

    属性

    pos   匹配的目标字符串开始位置
    endpos  匹配的目标字符串结束位置
    re     正则表达式
    string  目标字符串
    lastgroup  最后一组的名称
    lastindex  最后一组的序号

    方法

    span()  获取匹配内容的起止位置
    start() 获取匹配内容的开始位置
    end()   获取匹配内容的结束位置
    groupdict()  获取捕获组字典,组名为键,对应内容为值
    groups() 获取子组对应内容
    group(n = 0)

    功能  获取match对象匹配内容

    参数  

      默认为0表示获取整个match对象内容

      如果是序列号或者组名则表示获取对应子组内容

    返回值  匹配字符串

    import re
    import sys
    
    port = sys.argv[1]
    
    f = open('1.txt')
    
    # 找到端口所在的对应段落
    while True:
        data = ''
        for line in f:
            if line != '
    ':
                data += line
            else:
                break
        if not data:
            print("No PORT")
            break
    
        # 通过首单词比对是否为目标段
        try:
            PORT = re.match(r'S+', data).group()
        except Exception:
            continue
        if port == PORT:
            # pattern=r"[0-9a-f]{4}.[0-9a-f]{4}.[0-9a-f]{4}"
            pattern = r"address is ((d{1,3}.){3}d{1,3}/d+|Unknown)"
            address = re.search(pattern, data).group(1)
            print(address)
            break
    
    f.close()
    找到端口所在的对应段落

    search

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

    功能  匹配目标字符串第一个符合内容

    参数  

      pattern 正则

      string 目标字符串

    返回值  匹配内容match object

    flags

    扩展丰富正则表达式的匹配功能

    可调用的函数

    re.compile,re.findall,re.search....

    常用 flag

    A == ASCII  元字符只能匹配ascii码
    I == IGNORECASE  匹配忽略字母大小写
    S == DOTALL  使 . 可以匹配换行
    M == MULTILINE  使 ^  $可以匹配每一行的开头结尾位置
    X == VERBOSE  为正则添加注释

    使用多个flag

    flags = re.I | re.A

    实例

    import  re 
    
    # 只匹配ascii字符
    # regex = re.compile(r'w+',flags=re.A)
    
    # 忽略字母大小写
    # regex = re.compile(r'[A-Z]+',flags=re.I)
    
    # . 可以匹配换行
    # regex = re.compile(r'.+',flags=re.S)
    
    # 匹配每一行开始位置
    # regex = re.compile(r'^北京',flags=re.M)
    
    # 为正则添加注释
    pattern = r'''[A-Z][a-z]* #匹配第一个单词
    s+w+s+ #匹配空行和第二个单词
    w+ #匹配汉字
    '''
    regex = re.compile(pattern,flags=re.X)
    
    s = '''Welcome to
    北京
    '''
    l = regex.findall(s)
    print(l)
    flag 实例

     split

    split(pattern, string, maxsplit=0, flags=0)

    功能  实现对字符串的正则切割, 可以进行多个分隔符进行切割

    参数  正则, 被切割字符串, 保留个数, flag 

    import re
    
    s = "sda.sda'sda/sda1adsa-ada.sad"
    print(re.split("[./'-]+", s))
    # ['sda', 'sda', 'sda', 'sda1adsa', 'ada', 'sad']
    import re
    
    s = "sda.sda'sda/sda1adsa-ada.sad"
    print(re.split("[./'-]+", s, maxsplit=3))
    # ['sda', 'sda', 'sda', 'sda1adsa-ada.sad']
  • 相关阅读:
    Linux下查看文件和文件夹大小的df和du命令(链接)
    路由的原理和作用[赛迪网]
    select 好用插件
    如何启动/停止/重启MySQL
    Spirng quartz 整合
    String,StringBuffer与StringBuilder的区别
    如何给input[file]定义cursor
    dns简介
    浏览器高级对象
    shell 学习文章列表
  • 原文地址:https://www.cnblogs.com/shijieli/p/10485404.html
Copyright © 2011-2022 走看看