• Python 正则表达式的使用


    正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本,Python使用re模块来处理正则表达式。

    一、正则表达式
    1、通配符
    句点 . 与除换行符外的任何字符都匹配,并且只与一个字符匹配。
    例如正则表达式'.ython'与字符串'python'匹配,不与'cpython'或'ython'匹配。
    2、特殊字符转义
    用两个反斜杠转义,如果用单个反斜杠,则前面字符串加r。
    例如模式'python\.org',或r'python.org'匹配字符串'python.org'。
    3、字符集
    字符集用方括号将一个子串括起,字符集只能匹配一个字符,如 '[pj]ython'与'python'和'jython'都匹配;
    也可以使用用范围,如'[a-zA-Z0-9]'与大写字母、小写字母和数字都匹配;
    要指定排除字符集,在开头添加一个^字符,如'[^ab]'与除a、b外的其他任何字符都匹配。
    4、二选一和子模式
    使用管道字符 | 表示匹配两个中的一个 ,如'python|perl' 匹配'python'和'perl'。
    如果只想将 | 用于模式的一部分,可将这部分(子模式)放在圆括号内。如'p(ython|erl)'。
    单个字符也可称为子模式。
    5、字符串的开头和结尾
    开头用脱字符 ^,结尾用美元符号 $。
    6、可选模式和重复模式
    在子模式后面加上指定符号 ,可指定可选和重复模式。
    (pattern)? : pattern可重复0、1
    (pattern)* : pattern可重复0、1或多次
    (pattern)+ : pattern可重复1或多次
    (pattern){m,n} : pattern可重复m至n次
    重复运算符默认是贪婪的,匹配尽可能多的内容。
    如r'*(.+)*'匹配字符串 '*This* is *it*!'时将匹配到*This* is *it*
    在重复运算符后面加问号?可指定为非贪婪的,
    如r'*(.+?)*'匹配字符串 '*This* is *it*!'时将匹配到*This* 和 *it*

    二、模板re包含使用正则表达式的函数。

    1、search(pattern, string[, flags])

    (1)在给定字符串查找第一个与正则表达式匹配的子串,如果找到将返回MatchObject对象(结果为真),否则返回None(结果为假)
    参数 pattern 为正则表达式,string 为要匹配的字符串,flags为标志位,控制是否区分大小写等等。
    (2)MatchObject对象
    MatchObject对象包含与模式匹配的子串的信息,这些子串部分称为编组。
    编组就是放在圆括号内的子模式,根据左边的括号数编号,其中编组0指的是整个模式。
    MatchObject对象的几个重要方法
    groups() 返回一个包含所有编组字符串的元组,从 1 到 所含的编组,不包含编组0。
    group([group1, ...]) 获取与给定子模式(编组)匹配的子串,没有指定编组号则默认为0
    start([group]) 返回与给定编组匹配的子串的起始位置
    end([group]) 返回与给定编组匹配的子串的终止位置(与切片一样不包含终止位置)
    span([group]) 返回与给定编组匹配的子串的起始位置和终止位置

    import re
    
    m = re.search(r'www.(.*).(.{3})', 'WWW.python.org', re.I) #忽略大小写
    if(m):
        print(m.groups()) #从编组1算起
    
        print('编组0:')
        print(m.group()) 
        print(m.group(0))
    
        print('编组1:')
        print(m.group(1))
        print(m.start(1))
        print(m.end(1))
        print(m.span(1))
    
        print('编组2:')
        print(m.group(2))
        print(m.start(2))
        print(m.end(2))
        print(m.span(2))

    运行结果:

    ('python', 'org')
    编组0:
    www.python.org
    www.python.org
    编组1:
    python
    4
    10
    (4, 10)
    编组2:
    org
    11
    14
    (11, 14)

    2、match(pattern, string[, flags])

    match函数与search函数类似,不同之处是在给定字符串开头查找与正则表达式匹配的子串。

    import re
    
    m1 = re.search(r'python', 'www.python.org')
    if(m1):
        print('search匹配成功')
    else:
        print('search匹配失败')
    
    m2 = re.match(r'python', 'www.python.org')
    if(m2):
        print('match匹配成功')
    else:
        print('match匹配失败')

    运行结果:

    search匹配成功
    match匹配失败

    3、compile(pattern[, flags])

    调用search、match等函数时,如果提供的是用字符串表示的正则表达式,内部会将它们转换为模式对象。
    compile将字符串表示的正则表达式转换为模式对象,内部无需再进行转换。
    模式对象也有搜索/匹配方法,因此
    pat = re.compile(pattern[, flags])
    pat.search(string) (pat是使用 compile创建的模式对象)
    等价于re.search(pattern, string[, flags])

    import re
    
    m1 = re.search(r'python', 'www.python.org')
    if(m1):
        print('search匹配成功')
    else:
        print('search匹配失败')
    
    pat = re.compile(r'python')
    m2 = pat.search('www.python.org')
    if(m1):
        print('compile search匹配成功')
    else:
        print('compile search匹配失败')

    运行结果:

    search匹配成功
    compile search匹配成功

    4、split(pattern, string[, maxsplit=0])

    根据模式来分割字符串,返回列表

    import re
    
    res = re.split('[, ]', 'ab,cd 123') #以空格和逗号为分隔符来分割
    print(res)

    运行结果:

    ['ab', 'cd', '123']

    5、findall(pattern, string)

    返回一个列表,其中包含字符串中所有与模式匹配的子串

    import re
    
    result = re.findall(r'd+', 'ab,cd 123 456') #查找数字
    print(result)

    运行结果:

    ['123', '456']

    6、sub(pattern, repl, string[, count=0])

    将字符串中与模式pattern匹配的子串都替换为repl

    import re
    
    result = re.sub(r'D', '', 'abc123def')
    print(result)

    运行结果:

    123

     三、实例:抓取博客园首页的信息

    目标:抓取首页的每篇文章的标题、文章url、作者、发布日期。

    查看html源码,每篇文章的源码类似如下:

    <div class="post_item_body">
        <h3><a class="titlelnk" href="https://www.cnblogs.com/mukekeheart/p/11395063.html" target="_blank">iOS学习——iOS 宏(define)与常量(const)的正确使用</a></h3>                   
        <p class="post_item_summary">
    <a href="https://www.cnblogs.com/mukekeheart/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/926487/20180313105754.png" alt=""/></a>    概述 在iOS开发中,经常用到宏定义,或用const修饰一些数据类型,经常有开发者不知怎么正确使用,导致项目中乱用宏与const修饰。你能区分下面的吗?知道什么时候用吗? 当我们想全局共用一些数据时,可以用宏、变量、常量 宏、变量、常量之间的区别 宏:只是在预处理器里进行文本替换,没有类型,不做任何 ...
        </p>              
        <div class="post_item_foot">                    
        <a href="https://www.cnblogs.com/mukekeheart/" class="lightblue">mukekeheart</a> 
        发布于 2019-08-22 16:23 
        <span class="article_comment"><a href="https://www.cnblogs.com/mukekeheart/p/11395063.html#commentform" title="0001-01-01 08:05" class="gray">
            评论(0)</a></span><span class="article_view"><a href="https://www.cnblogs.com/mukekeheart/p/11395063.html" class="gray">阅读(19)</a></span></div>
    </div>

    经过多次测试调整正式表达式,最终代码如下:

    # -*- coding:utf-8 -*-
    
    from urllib.request import urlopen
    import re
    
    #参数re.DOTALL使得表达式中的句点匹配包括换行符在内的所有字符
    p = re.compile('<a class="titlelnk" href="(.*?)".*?>(.*?)</a>.*?<div class="post_item_foot">.*?<a href=".+?" class="lightblue">(.*?)</a>.*?(\d{4}-\d{2}-\d{2} \d{2}:\d{2}).*?<span.*?', re.DOTALL)
    text = urlopen('https://www.cnblogs.com').read().decode()
    print(p.findall(text))

    运行结果如下:

  • 相关阅读:
    Hadoop 0.23.1 Release Notes
    maven编译参数
    Hadoop快速入门
    HTML Parser HTML Parser
    EasyHadoop v1.0
    Hudson+Maven+SVN 快速搭建持续集成环境
    对技术要有足够的尊重和敬畏
    hudson设置
    python之强大的日志模块 竹叶青 的专栏 博客频道 CSDN.NET
    PHP学习之七:错误控制运算符
  • 原文地址:https://www.cnblogs.com/gdjlc/p/11389869.html
Copyright © 2020-2023  润新知