• re模块


    一.re模块

    1.什么是正则?

     正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

    元字符 匹配内容
    w 匹配字母(包含中文)或数字或下划线
    W 匹配非字母(包含中文)或数字或下划线
    s 匹配任意的空白符
    S 匹配任意非空白符
    d 匹配数字
    D 匹配非数字
    A 从字符串开头匹配
    z 匹配字符串的结束,如果是换行,只匹配到换行前的结果
    匹配一个换行符
    匹配一个制表符
    ^ 匹配字符串的开始
    $ 匹配字符串的结尾
    . 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
    [...] 匹配字符组中的字符
    [...](https://guobaoyuan.gitee.io/new_book/Python/19-0 re.html#fn_...) 匹配除了字符组中的字符的所有字符
    * 匹配0个或者多个左边的字符。
    + 匹配一个或者多个左边的字符。
    匹配0个或者1个左边的字符,非贪婪方式。
    {n} 精准匹配n个前面的表达式。
    {n,m} 匹配n到m次由前面的正则表达式定义的片段,贪婪方式
    ab 匹配a或者b
    () 匹配括号内的表达式,也表示一个组

    ------------------------------------------------匹配模式----------------------------------------------------

    我们现在配合着正则表达式来进行测试

    1.字符串的常用操作:一对一匹配

    s1 = 'meet郭宝元'
    print(s1.find('宝元'))
    

    2.正则匹配

    w 匹配中文,字母,数字,下划线

    import re
    name = "宝元-meet_123 "
    print(re.findall("w",name))
    #结果
    ['宝', '元', 'm', 'e', 'e', 't', '_', '1', '2', '3']
    

    W 不匹配中文,字母,数字,下划线

    import re
    name = "宝元-meet_123 "
    print(re.findall("W",name))
    # 结果
    ['-',' ']
    

    s 匹配任意的空白符

    import re
    name = "宝元-meet_123 "
    print(re.findall("s",name))
    # 结果
    [' ']
    

    S 匹配不是任意的空白符

    import re
    name = "宝元-meet_123 "
    print(re.findall("s",name))
    # 结果
    ['宝', '元', '-', 'm', 'e', 'e', 't', '_', '1', '2', '3']
    

    d 匹配数字

    import re
    name = "宝元-meet_123 "
    print(re.findall("d",name))
    # 结果
    ['1', '2', '3']
    

    D 匹配非数字

    import re
    name = "宝元-meet_123 "
    print(re.findall("D",name))
    # 结果
    ['宝', '元', '-', 'm', 'e', 'e', 't', '_', ' ']
    

    A 与 ^ 从字符串开头匹配

    import re
    name = "宝元-meet_123 "
    print(re.findall("A宝元",name))
    # 结果
    ['宝元']
    
    import re
    name = "宝元-meet_123 "
    print(re.findall("A宝元",name))
    # 结果
    ['宝元']
    

     与 z 与 $ 字符串结尾匹配

    import re
    name = "宝元-meet_123 "
    print(re.findall("123 ",name))
    # 结果
    ['123 ']
    
    import re
    name = "宝元-meet_123 "
    print(re.findall("123 ",name))
    # 结果
    ['123 ']
    
    import re
    name = "宝元-meet_123 "
    print(re.findall("123 $",name))
    # 结果
    ['123 ']
    
    

    匹配换行符合制表符

    import re
    name = "宝元-meet_123	 
    "
    print(re.findall("
    ",name))
    # 结果
    ['
    ']
    
    import re
    name = "宝元-meet_123	 
    "
    print(re.findall("	",name))
    # 结果
    ['	']
    
    

    ------------------------------------------------匹配方式----------------------------------------------------

    . 匹配任意字符(换行符除外)

    import re
    name = "宝元-meet_123	 
    "
    print(re.findall(".",name))
    # 结果
    ['宝', '元', '-', 'm', 'e', 'e', 't', '_', '1', '2', '3', '	', ' ']
    
    

    . 匹配任意字符

    import re
    name = "宝元-meet_123	 
    "
    print(re.findall(".",name,re.DOTALL))
    # 结果
    ['宝', '元', '-', 'm', 'e', 'e', 't', '_', '1', '2', '3', '	', '
    ']
    
    

    ? 匹配?前元素0个或1个

    import re
    name = "m-e-me-meet-meet_123	 
    "
    print(re.findall("me?",name))
    # 结果
    ['m', 'me', 'me', 'me']
    
    

    ***** 匹配 * 前面元素0个或多个 [贪婪匹配]

    import re
    name = "m-e-me-meet-meet_123	 
    "
    print(re.findall("*",name))
    # 结果
    ['m', 'me', 'mee', 'mee']
    
    

    + 匹配 +前面元素1个或多个 [贪婪匹配]

    import re
    name = "m-e-me-meet-meet_123	 
    "
    print(re.findall("me+",name))
    # 结果
    ['me', 'mee', 'mee']
    
    

    {n,m} 匹配n到m个元素

    import re
    name = "m-e-me-meet-meet_123	 
    "
    print(re.findall("e{1,2}",name))
    # 结果
    ['e', 'e', 'ee', 'ee']
    
    

    .* 任意内容0个或多个

    import re
    name = "m-e-me-meet-meet_123	 
    "
    print(re.findall(".*",name))
    # 结果
    ['m-e-me-meet-meet_123', '']
    
    

    .*? 任意内容0个或1个

    import re
    name = "m-e-me-meet-meet_123"
    print(re.findall("m.*?e",name))
    # 结果
    ['m-e', 'me', 'mee', 'mee']
    
    import re
    name = "m-e-me-meet-meet_123"
    print(re.findall("m.?e",name))
    # 结果
    ['m-e', 'me', 'mee', 'mee']
    
    

    [] 获取括号中的内容

    import re
    name = "m-e-me-meet-meet_123"
    print(re.findall("[1-9]",name))
    # 结果
    ['1', '2', '3']
    # []中的-是什么至什么不会匹配-
    
    import re
    name = "m-e-me-meet-meet_123"
    print(re.findall("[a-z]",name))
    # 结果
    ['m', 'e', 'm', 'e', 'm', 'e', 'e', 't', 'm', 'e', 'e', 't']
    
    import re
    name = "m-e-me-meet-meet_123"
    print(re.findall("[A-z]",name))
    # 结果
    ['m', 'e', 'm', 'e', 'm', 'e', 'e', 't', 'm', 'e', 'e', 't', '_']
    # 是按照ascii码表位进行匹配的
    
    import re
    name = "m-e-me-meet-meet_123"
    print(re.findall("[a-zA-Z]",name))
    # 结果
    ['m', 'e', 'm', 'e', 'm', 'e', 'e', 't', 'm', 'e', 'e', 't']
    
    import re
    name = "m-e-me-meet-meet_123"
    print(re.findall("[^A-z]",name))
    # 结果
    ['-', '-', '-', '-', '1', '2', '3']
    # [^A-z] 有上尖号就是取反,获取不是字母和特定的几个字符
    
    如果想要匹配到-,就需要进行如下操作(将-号放到最前面)
    import re
    name = "m-e-me-meet-meet_123"
    print(re.findall("[-+*/]",name))
    # 结果
    ['-', '-', '-', '-']
    
    

    练习

    有如下字符串:'alex_sb ale123_sb wu12sir_sb wusir_sb ritian_sb' 的 alex wusir '

    找到所有带_sb的内容

    () 分组 定制一个匹配规则

    import re
    print(re.findall('(.*?)_sb', 'alex_sb wusir_sb 日天_sb'))
    # 结果
    ['alex', ' wusir', ' 日天']
    
    # 应用举例:
    print(re.findall('href="(.*?)"','<a href="http://www.baidu.com">点击</a>')
    # 结果
    ['http://www.baidu.com']
    
    

    | 匹配 左边或者右边

    import re
    print(re.findall('alex|宝元|wusir', 'alex宝元wusiraleeeex宝宝元odlb'))
    # 结果
    ['alex', '宝元', 'wusir', '宝元']
    
    import re
    print(re.findall('compan(day|morrow)','Work harder today than yesterday, and the day after tomorrow will be better'))
    # 结果
    ['day', 'morrow']
    
    import re
    print(re.findall('compan(?:day|morrow)','Work harder today than yesterday, and the day after tomorrow will be better'))
    # 结果
    ['today', 'tomorrow']
    # 分组() 中加入?: 表示将整体匹配出来而不只是()里面的内容。
    
    

    ------------------------------------------------常用方法----------------------------------------------------

    findall 全部找到返回一个列表

    import re
    print(re.findall("alex","alexdsb,alex_sb,alexnb,al_ex"))
    # 结果
    ['alex', 'alex', 'alex']
    
    

    search 从字符串中任意位置进行匹配查找到一个就停止了,返回的是一个对象. 获取匹配的内容必须使用.group()进行获取

    import re
    print(re.search("sb|nb","alexdsb,alex_sb,alexnb,al_ex").group())
    # 结果
    sb
    
    

    match 从字符串开始位置进行匹配

    import re
    print(re.match('meet', 'meet alex wusir 日天').group())
    # 结果
    meet
    
    import re
    print(re.match('alex', 'meet alex wusir 日天'))
    # 结果
    None
    
    

    split 分隔 可按照任意分隔符进行分隔

    import re
    print(re.split('[ ::,;;,]','alex wusir,日天,太白;女神;肖锋:吴超'))
    # 结果
    ['alex', 'wusir', '日天', '太白', '女神', '肖锋', '吴超']
    
    

    sub 替换

    import re
    print(re.sub('barry', 'meet', 'barry是最好的讲师,barry就是一个普通老师,请不要将barry当男神对待。'))
    # 结果
    meet是最好的讲师,meet就是一个普通老师,请不要将meet当男神对待。
    
    

    compile 定义匹配规则

    import re
    obj = re.compile('d{2}')
    print(obj.findall("alex12345"))
    # 结果
    ['12', '34']
    
    import re
    ['12', '34']
    obj = re.compile('d{2}')
    print(obj.search("alex12345").group())
    # 结果
    12
    
    

    finditer 返回一个迭代器

    import re
    g = re.finditer('al',"alex_alsb,al22,aladf")
    print(next(g).group())
    print([i.group() for i in g])
    # 结果
    al
    ['al','al','al']
    
    

    给分组起名字

    import re
    ret = re.search("<(?P<tag_name>w+)>w+</w+>","<h1>hello</h1>")
    print(ret.group("tag_name"))
    print(ret.group())
    # 结果
    h1
    <h1>hello</h1>
    
    import re
    ret = re.search(r"<(w+)>w+</1>","<h1>hello</h1>")
    print(ret.group(1))
    print(ret.group())
    
    

    相关练习:

    1 "1-2*(60+(-40.35/5)-(-4*3))"
    1.1 匹配所有的整数
    print(re.findall('d+',"1-2*(60+(-40.35/5)-(-4*3))"))
    1.2 匹配所有的数字(包含小数)
    print(re.findall(r'd+.?d*|d*.?d+', "1-2*(60+(-40.35/5)-(-4*3))"))
    1.3 匹配所有的数字(包含小数包含负号)
    print(re.findall(r'-?d+.?d*|d*.?d+', "1-2*(60+(-40.35/5)-(-4*3))"))
    
    2,匹配一段你文本中的每行的邮箱
    http://blog.csdn.net/make164492212/article/details/51656638 匹配所有邮箱
    
    3,匹配一段你文本中的每行的时间字符串 这样的形式:'1995-04-27'
    
    s1 = '''
    时间就是1995-04-27,2005-04-27
    1999-04-27 老男孩教育创始人
    老男孩老师 alex 1980-04-27:1980-04-27
    2018-12-08
    '''
    print(re.findall('d{4}-d{2}-d{2}', s1))
    
    4 匹配 一个浮点数
    print(re.findall('d+.d*','1.17'))
    
    5 匹配qq号:腾讯从10000开始:
    print(re.findall('[1-9][0-9]{4,}', '2413545136'))
    
    s1 = '''
    <div id="cnblogs_post_body" class="blogpost-body"><h3><span style="font-family: 楷体;">python基础篇</span></h3>
    <p><span style="font-family: 楷体;">&nbsp; &nbsp;<strong><a href="http://www.cnblogs.com/guobaoyuan/p/6847032.html" target="_blank">python 基础知识</a></strong></span></p>
    <p><span style="font-family: 楷体;"><strong>&nbsp; &nbsp;<a href="http://www.cnblogs.com/guobaoyuan/p/6627631.html" target="_blank">python 初始python</a></strong></span></p>
    <p><span style="font-family: 楷体;"><strong>&nbsp; &nbsp;<strong><a href="http://www.cnblogs.com/guobaoyuan/articles/7087609.html" target="_blank">python 字符编码</a></strong></strong></span></p>
    <p><span style="font-family: 楷体;"><strong><strong>&nbsp; &nbsp;<a href="http://www.cnblogs.com/guobaoyuan/articles/6752157.html" target="_blank">python 类型及变量</a></strong></strong></span></p>
    <p><span style="font-family: 楷体;"><strong>&nbsp; &nbsp;<a href="http://www.cnblogs.com/guobaoyuan/p/6847663.html" target="_blank">python 字符串详解</a></strong></span></p>
    <p><span style="font-family: 楷体;">&nbsp; &nbsp;<strong><a href="http://www.cnblogs.com/guobaoyuan/p/6850347.html" target="_blank">python 列表详解</a></strong></span></p>
    <p><span style="font-family: 楷体;"><strong>&nbsp; &nbsp;<a href="http://www.cnblogs.com/guobaoyuan/p/6850496.html" target="_blank">python 数字元祖</a></strong></span></p>
    <p><span style="font-family: 楷体;">&nbsp; &nbsp;<strong><a href="http://www.cnblogs.com/guobaoyuan/p/6851820.html" target="_blank">python 字典详解</a></strong></span></p>
    <p><span style="font-family: 楷体;"><strong>&nbsp; &nbsp;<strong><a href="http://www.cnblogs.com/guobaoyuan/p/6852131.html" target="_blank">python 集合详解</a></strong></strong></span></p>
    <p><span style="font-family: 楷体;"><strong>&nbsp; &nbsp;<a href="http://www.cnblogs.com/guobaoyuan/articles/7087614.html" target="_blank">python 数据类型</a>&nbsp;</strong></span></p>
    <p><span style="font-family: 楷体;"><strong>&nbsp; &nbsp;<a href="http://www.cnblogs.com/guobaoyuan/p/6752169.html" target="_blank">python文件操作</a></strong></span></p>
    <p><span style="font-family: 楷体;"><strong>&nbsp; &nbsp;<a href="http://www.cnblogs.com/guobaoyuan/p/8149209.html" target="_blank">python 闭包</a></strong></span></p>
    <p><span style="font-family: 楷体;"><strong>&nbsp; &nbsp;<a href="http://www.cnblogs.com/guobaoyuan/articles/6705714.html" target="_blank">python 函数详解</a></strong></span></p>
    <p><span style="font-family: 楷体;"><strong>&nbsp; &nbsp;<a href="http://www.cnblogs.com/guobaoyuan/articles/7087616.html" target="_blank">python 函数、装饰器、内置函数</a></strong></span></p>
    <p><span style="font-family: 楷体;"><strong>&nbsp; &nbsp;<a href="http://www.cnblogs.com/guobaoyuan/articles/7087629.html" target="_blank">python 迭代器 生成器</a>&nbsp;&nbsp;</strong></span></p>
    <p><span style="font-family: 楷体;"><strong>&nbsp; &nbsp;<a href="http://www.cnblogs.com/guobaoyuan/articles/6757215.html" target="_blank">python匿名函数、内置函数</a></strong></span></p>
    </div>
    '''
    1,找到所有的span标签的内容
    ret = re.findall('<span(.*?)>', s1)
    print(ret)
    
    2,找到所有a标签对应的url
    print(re.findall('<a href="(.*?)".*?</a>',s1))
    
    

    二 . logging模块

    我们来说一下这个logging模块,这个模块的功能是记录我们软件的各种状态,你们现在和我一起找到红蜘蛛的那个图标,然后右键找一找是不是有个错误日志.其实每个软件都是有错误日志的,开发人员可以通过错误日志中的内容对他的程序进行修改

    这只是一种应用场景,有的还会将日志用于交易记录.比如你给我转账应该做记录吧,

    我们使用的信用卡,每消费的一笔都会记录,我们来看看这个日志怎么用?

    我们先来看一下函数式简单配置

    import logging  
    logging.debug('debug message')  
    logging.info('info message')  
    logging.warning('warning message')  
    logging.error('error message')  
    logging.critical('critical message')
    
    

    默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING

    (日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG),

    默认的日志格式为日志级别:Logger名称:用户输出消息。

    我们自己用函数写的这个可以正常使用但是不够灵活,我们看看这个灵活的

    灵活配置日志级别,日志格式,输出位置:

    import logging  
    logging.basicConfig(level=logging.DEBUG,  
                        format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',  
                        datefmt='%a, %d %b %Y %H:%M:%S',  
                        filename='/tmp/test.log',  
                        filemode='w')  
    
    logging.debug('debug message')  
    logging.info('info message')  
    logging.warning('warning message')  
    logging.error('error message')  
    logging.critical('critical message')
    
    

    basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:

    • filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
    • filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
    • format:指定handler使用的日志显示格式。
    • datefmt:指定日期时间格式。
    • level:设置记录日志的级别
    • stream:用指定的stream创建StreamHandler。可以指定输出到
    • sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。

    format参数中可能用到的格式化串

    • %(name)s Logger的名字
    • %(levelno)s 数字形式的日志级别
    • %(levelname)s 文本形式的日志级别
    • %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
    • %(filename)s 调用日志输出函数的模块的文件名
    • %(module)s 调用日志输出函数的模块名
    • %(funcName)s 调用日志输出函数的函数名
    • %(lineno)d 调用日志输出函数的语句所在的代码行
    • %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
    • %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
    • %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
    • %(thread)d 线程ID。可能没有
    • %(threadName)s 线程名。可能没有
    • %(process)d 进程ID。可能没有
    • %(message)s用户输出的消息

    logger对象配置

    import logging
    
    logger = logging.getLogger()
    # 创建一个handler,用于写入日志文件
    fh = logging.FileHandler('test.log',encoding='utf-8') 
    
    # 再创建一个handler,用于输出到控制台 
    ch = logging.StreamHandler() 
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    
    fh.setLevel(logging.DEBUG)
    
    fh.setFormatter(formatter) 
    ch.setFormatter(formatter) 
    logger.addHandler(fh) #logger对象可以添加多个fh和ch对象 
    logger.addHandler(ch) 
    
    logger.debug('logger debug message') 
    logger.info('logger info message') 
    logger.warning('logger warning message') 
    logger.error('logger error message') 
    logger.critical('logger critical message')
    
    

    logging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。另外,可以通过:logger.setLevel(logging.Debug)设置级别,当然,也可以通过

    fh.setLevel(logging.Debug)单对文件流设置某个级别。

    python
  • 相关阅读:
    168. Excel Sheet Column Title
    171. Excel Sheet Column Number
    264. Ugly Number II java solutions
    152. Maximum Product Subarray java solutions
    309. Best Time to Buy and Sell Stock with Cooldown java solutions
    120. Triangle java solutions
    300. Longest Increasing Subsequence java solutions
    63. Unique Paths II java solutions
    221. Maximal Square java solutions
    279. Perfect Squares java solutions
  • 原文地址:https://www.cnblogs.com/bky20061005/p/12144652.html
Copyright © 2020-2023  润新知