zoukankan      html  css  js  c++  java
  • python学习第18天

    一.正则表达式

    1.匹配单个字符

    import re

    lst = re.findall(正则表达式,要匹配的字符串)
    返回列表,按照正则表达式匹配到的内容都扔到列表里
    最好在正则表达式和要匹配的字符串前面都加上r,原型化输出字符串
    

    1.预定义字符集

    1. d匹配数字

    2. D匹配非数字

    3. w匹配字母或数字或下划线(正则函数中,支持中文的匹配)

    4. W匹配非字母或数字或下划线

    5. s匹配任意的空白符( )

    6. S匹配任意非空白符

    7. 匹配一个换行符

    8. 匹配一个制表符

    9. .匹配任意字符,除了换行符

    2.字符组 必须匹配中括号里列举的字符(默认必须选一个)

    lst = re.findall("[abc]","oputuopctyauobpt")
    print(lst)
    
    print(re.findall('a[abc]b','aab abb acb adb')) # aab abb acb
    
    print(re.findall('a[0123456789]b','a1b a2b a3b acb ayb'))#a1b a2b a3b 
    # 优化: -是一个特殊的字符,代表的是一个范围 0-9 0123456789
    print(re.findall('a[0-9]b','a1b a2b a3b acb ayb'))#a1b a2b a3b 
    
    print(re.findall('a[abcdefg]b','a1b a2b a3b acb ayb adb')) #acb adb
    # 优化: [a-g]  如果想要表达所有的26个小写字母[a-z]
    print(re.findall('a[a-g]b','a1b a2b a3b acb ayb adb')) #acb adb
    
    print(re.findall('a[ABCDEFG]b','a1b a2b a3b  aAb aDb aYb')) #aAb aDb
    # 优化: [A-G]  如果想要表达所有的26个大写字母[A-Z]
    print(re.findall('a[A-G]b','a1b a2b a3b  aAb aDb aYb')) #aAb aDb
    
    print(re.findall('a[0-9a-zA-Z]b','a-b aab aAb aWb aqba1b')) #aab aAb aWb aqb a1b
    # 注意: [0-z] 数字 小写 大写 还有特殊字符 比如@ ... 
    print(re.findall('a[0-z]b','a@b aab aAb aWb aqba1b')) # a@b aab aAb aWb aqb a1b
    
    print(re.findall('a[0-9][*#/]b','a1/b a2b a29b a56b a456b')) # a1/b
    
    

    ^ 在字符组当中,代表除了,放到字符组的左边第一个位置

    如果想要匹配^或者 - 或者,可在原来的字符前面加上,让字符的含义失效

    print(re.findall('a[^-+*/]b',"a%b ccaa*bda&bd")) # a%b a&b
    lst = re.findall(r"e[^-]f","e^f e-f")
    
    lst = re.findall(r"a\c","ac")
    print(lst)	#a\c
    print(lst[0])#ac
    

     -> 转义字符 代表退格键backspace

    2.匹配多个字符

    1.量词练习

    1. ?匹配0个或者一个
    print(re.findall('a?b','abbzab abb aab'))  # ab  b ab ab b ab
    
    1. +匹配一个或者多个
    print(re.findall('a+b','b ab aaaaaab abb')) # ab aaaaaab ab
    
    1. *匹配0个或者多个
    print(re.findall('a*b','b ab aaaaaab abbbbbbb')) # b ab aaaaaab ab b b b b b b
    
    1. {m,n}匹配m个至n个
    # (1) 1 <= x <= 3
    print(re.findall('a{1,3}b','aaab ab aab abbb aaz aabb')) # aaab ab aab ab aab
    # (2) 前面修饰的a , 必须是2个字符
    print(re.findall('a{2}b','aaab ab aab abbb aaz aabb')) # aab aab aab
    # (3) 前面修饰的a , 至少是2个字符
    print(re.findall('a{2,}b','aaab ab aab abbb aaz aabb')) # aaab aab aab
    
    

    2.贪婪模式与非贪婪模式

    贪婪模式:默认向更多次匹配,底层用的是回溯算法

    非贪婪模式:默认向更少次匹配,用一个?号来进行修饰(修饰在量词的身后)

    (1)量词( * ? + {} )加上问号?表示非贪婪 惰性匹配
    (2)例:.*?w  表示匹配任意长度任意字符遇到一个w就立即停止
    

    回溯算法:从左向右进行匹配,一直到最后,直到最后再也匹配不到了,回头寻找最后一个

    . 是匹配任意字符,除了换行符

    strvar = "刘能和刘老根和刘铁棍子777子888"
    lst = re.findall("刘.",strvar)
    print(lst) # ['刘能', '刘老', '刘铁']
    
    # 贪婪模式
    lst = re.findall("刘.?",strvar)
    print(lst) # ['刘能', '刘老', '刘铁']
    
    lst = re.findall("刘.+",strvar)
    print(lst) # ['刘能和刘老根和刘铁棍子777子888']
    
    lst = re.findall("刘.*",strvar)
    print(lst) # ['刘能和刘老根和刘铁棍子777子888']
    
    lst = re.findall("刘.{1,21}",strvar)
    print(lst) # ['刘能和刘老根和刘铁棍子777子888']
    
    lst = re.findall("刘.*子",strvar)
    print(lst) # ['刘能和刘老根和刘铁棍子777子']
    
    # 非贪婪模式
    lst = re.findall("刘.??",strvar)
    print(lst) # ['刘', '刘', '刘']
    
    lst = re.findall("刘.+?",strvar)
    print(lst) # ['刘能', '刘老', '刘铁']
    
    lst = re.findall("刘.*?",strvar)
    print(lst) # ['刘', '刘', '刘']
    
    lst = re.findall("刘.{1,21}?",strvar)
    print(lst) # ['刘能', '刘老', '刘铁']
    
    lst = re.findall("刘.*?子",strvar)
    print(lst) # ['刘能和刘老根和刘铁棍子']
    
    

    3.边界符  ^ $

    1) 本身是一个转义字符 backspace

    边界字符 卡单词 word

    卡住左边界 w

    卡住有边界 d

    strvar = "word pwd scf"
    lst = re.findall(r".*d",strvar)
    print(lst) # ['word pwd']
    
    lst = re.findall(r".*?d",strvar)
    print(lst) # ['word', ' pwd']
    
    lst = re.findall(r"w",strvar)
    print(lst) # ['w']
    
    lst = re.findall(r"w.*?",strvar)
    print(lst) # ['w']
    
    # 正则表达式中写字符时,要谨慎,下面例子必须匹配到第一个空格时,才结束
    lst = re.findall(r"w.*? ",strvar)
    print(lst) # ['word ']
    
    lst = re.findall(r"wS*",strvar)
    print(lst) # ['word']^  $
    
    1. ^ $

    ^ 必须以..开头

    $ 必须以..结尾

    如果出现了^ $,要把字符串看成一个整体

    strvar = "大哥大嫂大爷"
    print(re.findall('大.',strvar))  # ['大哥', '大嫂', '大爷']
    print(re.findall('^大.',strvar)) # ['大哥']
    print(re.findall('大.$',strvar)) # ['大爷']
    print(re.findall('^大.$',strvar))# []
    print(re.findall('^大.*?$',strvar)) # ['大哥大嫂大爷']
    print(re.findall('^大.*?大$',strvar)) # []
    print(re.findall('^大.*?爷$',strvar)) # ['大哥大嫂大爷']
    
    print(re.findall('^g.*? ' , 'giveme 1gfive gay')) # ['giveme ']
    print(re.findall('five$' , 'aassfive'))  # five
    print(re.findall('^giveme$' , 'giveme')) # giveme
    print(re.findall('^giveme$' , 'giveme giveme'))# []
    print(re.findall('giveme' , 'giveme giveme')) # ['giveme', 'giveme']
    print(re.findall("^g.*e",'giveme 1gfive gay')) # ['giveme 1gfive']
    
    print(re.findall('g.*?', 'giveme 1gfive gay')) #['g', 'g', 'g']
    print(re.findall("^g.*?e",'giveme 1gfive gay'))#['give']
    

    4.命名分组

    1)分组练习(用圆括号),要所有的姓名

    print(re.findall('.*?_good','wusir_good alex_good secret男_good'))
    # ['wusir_good', ' alex_good', ' secret男_good']
    
    # () 显示括号里面匹配到的内容
    print(re.findall('(.*?)_good','wusir_good alex_good secret男_good'))
    # ['wusir', ' alex', ' secret男']
    # ?: 不优先显示括号里面的内容
    print(re.findall('(?:.*?)_good','wusir_good alex_good secret男_good'))
    # ['wusir_good', ' alex_good', ' secret男_good']
    
    1. | 代表或 , a|b 匹配字符a 或者 匹配字符b
    # 基本语法
    strvar = "abcddd"
    lst = re.findall("a|b",strvar) #['a', 'b']
    print(lst)
    # 注意事项
    # 匹配abc 或者 abcd
    """
    为了避免优先匹配前面的字符串,导致字符串匹配不完整,
    把较难匹配到的字符串写在前面,容易匹配到的字符串放在后面
    """
    strvar = "abc24234234ddabcd234234"
    # lst = re.findall("abc|abcd",strvar) 注意
    # print(lst) # ['abc', 'abc']
    lst = re.findall("abcd|abc",strvar)
    print(lst) # ["abc","abcd"]
    

    3)练习

    .  除了
    ,能够匹配到任意字符
      功效: 让有意义的字符变得无意义,或者让无意义的字符变得有意义
    . 让点原来的特殊含义失效,只是单纯的表达一个点字符.
    
    # (1)匹配小数 
    strvar = "5.33 3.13 34 34.  .98 9.99 sdfsdf  ......"
    # 整数.小数
    lst = re.findall(r"d+.d+",strvar)
    print(lst)	#['5.33', '3.13', '9.99']
    
    # (2)匹配小数和整数 
    # 整数.小数 34 43234 .
    # d+
    # d+.d+ 
    lst = re.findall(r"d+.d+|d+",strvar)
    print(lst) # ['5.33', '3.13', '34', '34', '98', '9.99']
    

    用分组形式来做

    findall 这个函数优先显示括号里面的内容,
    如果不想显示括号内容,使用?:, 显示实际匹配到的内容
    
    lst = re.findall(r"d+(?:.d+)?",strvar)
    print(lst) # ['5.33', '3.13', '34', '34', '98', '9.99']
    
    # 匹配135或171的手机号 
    strvar = "asdfasd234 13591199444 17188886666 19145547744"
    lst = re.findall("(?:135|171)d{8}",strvar)
    print(lst)
    
    # 卡主开头和结尾,数字必须是11位
    strvar = "13591199444"
    lst = re.findall("^(?:135|171)[0-9]{8}$",strvar)
    print(lst)
    

    4)search函数

    findall  把所有匹配到的字符串都搜出来,返回列表
           不能把分组内容和匹配的内容同时显示出来
                 
    search   只要搜索到一个结果就返回,返回对象.
            可以把分组内容和匹配的内容同时显示出来
           
    group : 对象.group()  直接获取匹配到的内容
    groups: 对象.groups() 直接获取分组里面的内容
    
    # 匹配www.baidu.com 或者 www.oldboy.com
    strvar = "www.baidu.com"
    lst = re.findall("(?:www).(?:baidu|oldboy).(?:com)",strvar)
    print(lst)
    
    obj = re.search("(www).(baidu|oldboy).(com)",strvar)
    print(obj)
    # 获取的是匹配到的数据
    print(obj.group())	#www.baidu.com
    # 获取的是分组里面的数据
    print(obj.groups())	#('www', 'baidu', 'com')
    # 获取第一个小括号里面的内容
    print(obj.group(1))
    # 获取第二个小括号里面的内容
    print(obj.group(2))
    # 获取第三个小括号里面的内容
    print(obj.group(3))
    

    案例

    # ### 案例: "5*6-7/3" 匹配 5*6 或者 7/3
    """search 在匹配不到时,返回的是None,无法使用group"""
    
    # 匹配出5*6
    strvar = "5*6-7/3"
    
    # 匹配出5*6
    obj = re.search(r"d+[*/]d+",strvar)
    print(obj)
    strvar1 = obj.group()
    print(strvar1) # 5*6
    
    # 按照*号分隔,算出乘积结果
    n1,n2 = strvar1.split("*")
    res1 = int(n1)*int(n2)
    print(res1)
    
    # 对字符串进行替换
    # strvar = "30-7/3"
    strvar2 = strvar.replace(strvar1,str(res1))
    print(strvar2) # 30-7/3
    
    # 匹配出 7/3
    obj = re.search(r"d+[*/]d+",strvar2)
    strvar3 = obj.group()
    print(strvar3) # 7/3
    
    # 按照/号分隔,算出除法结果
    n1,n2 = strvar3.split("/")
    res2 = int(n1)/int(n2)
    print(res2)
    
    # 对字符串进行替换
    strvar4 = strvar2.replace(strvar3,str(res2))
    print(strvar4)
    
    # 通过-号进行最后的分隔,算出最后的结果.
    n1,n2 = strvar4.split("-")
    res_finally = float(n1) - float(n2)
    print(res_finally)
    

    当不清楚字符串中含有什么内容的时候,用.*?进行取代

    1.反向引用

    # 1 代表反向引用,将第一个括号匹配的字符串,在1位置处在引用一次
    lst = re.findall(r"<(.*?)>(.*?)<(/1)>",strvar)
    print(lst)  # [('div', '明天就放假了,很开心', '/div')]
    
    # 1 代表第一个括号  2代表第二个括号
    strvar = "a1b2cab"
    obj = re.search(r"(.*?)d(.*?)d(.*?)12",strvar)
    print(obj)
    # 返回匹配到的字符串
    res = obj.group()
    print(res)
    # 返回匹配到的分组内容
    res = obj.groups()
    print(res)
    

    2.命名分组

    """
    # 2.命名分组 (给小组命名)
    3) (?P<组名>正则表达式) 给这个组起一个名字
    4) (?P=组名) 引用之前组的名字,把该组名匹配到的内容放到当前位置
    """
    # 方法一
    strvar = "a1b2cab"
    obj = re.search(r"(?P<tag1>.*?)d(?P<tag2>.*?)d(?P<tag3>.*?)12",strvar)
    print(obj.group()) # a1b2cab
    
    # 方法二
    strvar = "a1b2cab"
    obj = re.search(r"(?P<tag1>.*?)d(?P<tag2>.*?)d(?P<tag3>.*?)(?P=tag1)(?P=tag2)",strvar)
    print(obj.group()) # a1b2cab
    
  • 相关阅读:
    车载OS盘点及特点分析一:车载OS几大系统介绍
    CTF常用软件/工具
    汽车软件产业研究报告(2020年)
    高级加密标准(AES)分析
    工具 | CTP、SimNow、NSight、快期
    CTF之图片隐写术解题思路
    V2X和车路协同研究:5G V2X将成为数字座舱标配
    腾讯安全正式发布《IoT安全能力图谱》
    Microsoft Remote Desktop Beta 下载地址
    密码学初探|加密模式
  • 原文地址:https://www.cnblogs.com/yunchao-520/p/12940407.html
Copyright © 2011-2022 走看看