• day20:正则表达式


    单个字符的匹配

    findall(正则表达式,字符串) 把符合正则表达式的字符串存在列表中返回

    预定义字符集(8)

    d 匹配数字

    D 匹配非数字

    w 匹配数字字母下划线

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

    s 匹配任意的空白符

    S 匹配任意的非空白符

    匹配一个换行符

    匹配一个制表符

    # ### 预定义字符集
    # d 匹配数字
    strvar = "sdfsdf*(&*(&(2ui3"
    lst = re.findall("d",strvar)
    print(lst)
    
    # D 匹配非数字
    strvar = "sdfsdf*(&*(&(2ui3"
    lst = re.findall("D",strvar)
    print(lst)
    
    # w 匹配字母数字下划线
    strvar = "sadf*)(*_)456你你好"
    lst = re.findall("w",strvar)
    print(lst)
    
    # W 匹配非字母或数字或下划线
    strvar = "sadf*)(*_)456你你好"
    lst = re.findall("W",strvar)
    print(lst)
    
    
    # s 匹配任意的空白符 (
     	 
     ' ')
    strvar = "                      "
    lst = re.findall("s",strvar)
    print(lst)
    
    # S 匹配任意非空白符
    strvar = "    abdd                         "
    lst = re.findall("S",strvar)
    print(lst)
    
    
    # 
     匹配一个换行符
    strvar = """
    
    """
    lst = re.findall(r"
    ",strvar)
    print(lst)
    
    # 	 匹配一个制表符
    strvar = """
                    
    """
    lst = re.findall(r"	",strvar)
    print(lst)

    字符组

    必须从字符组列举出来的字符当中抽取,默认一个,如果没有返回空.

    # ### 字符组[] 必须从字符组列举出来的字符当中抽取,默认一个,如果没有返回空
    strvar = "abpoiuc"
    lst = re.findall("[abc]",strvar)
    print(lst) # ['a', 'b', 'c']
    
    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 0到9这么多的数字
    print(re.findall('a[0-9]b','a1b a2b a3b acb ayb'))  # a1b a2b a3b
    # a-g => abcdefg
    print(re.findall('a[abcdefg]b','a1b a2b a3b acb ayb adb')) # acb adb
    print(re.findall('a[a-g]b','a1b a2b a3b acb ayb adb'))     # acb adb
    # a-z => 26个小写字母
    print(re.findall('a[a-z]b','a1b a2b a3b acb ayb adb')) # acb ayb adb
    
    # A-G => ABCDEFG
    print(re.findall('a[ABCDEFG]b','a1b a2b a3b  aAb aDb aYb')) #aAb aDb
    print(re.findall('a[A-G]b','a1b a2b a3b  aAb aDb aYb')) #aAb aDb  
    # A-Z=> 26个大写字母
    print(re.findall('a[A-Z]b','a1b a2b a3b  aAb aDb aYb')) #aAb aDb aYb
    
    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_ba@b aab aAb aWb aqba1b')) # 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("a[^-]b","a+b a-b a^b")
    print(lst) # ['a-b', 'a^b'] 

    匹配 /

    # 匹配 
    """ 本身也是转义字符 : 退格(把光标向左移动一位)"""
    lst = re.findall(r"a\b",r"a")
    print(lst[0]) 

    多个字符的匹配

    量词(4)

    0-1

    1-N

    0-N

    {m,n}  M-N

    # 量词
    '''1) ? 匹配0个或者1个a '''
    print(re.findall('a?b','abbzab abb aab'))  # ab b ab ab b ab
    '''2) + 匹配1个或者多个a '''
    print(re.findall('a+b','b ab aaaaaab abb')) # ab aaaaaab ab
    '''3) * 匹配0个或者多个a '''
    print(re.findall('a*b','b ab aaaaaab abbbbbbb')) # b ab aaaaaab ab b b b b b b
    '''4) {m,n} 匹配m个至n个a '''
    # 1 <= x <= 3
    print(re.findall('a{1,3}b','aaab ab aab abbb aaz aabb')) # aaab ab aab ab aab
    # {2,} 至少2次
    print(re.findall('a{2,}b','aaab ab aab abbb aaz aabb')) # aaab aab aab
    # {2,} 必须2次
    print(re.findall('a{2}b','aaab ab aab abbb aaz aabb')) # aab aab aab

    贪婪匹配和非贪婪匹配

    1.贪婪匹配 : 默认向更多次数匹配(回溯算法)
     非贪婪匹配 : 默认向更少次数匹配

    2.非贪婪匹配在量词的后面接?
    例如:.?? .+? .*? {4,}?

    3.回溯算法 : 从左向右进行匹配,直到匹配到最后,再也找不到了,回头,找最后一个(递归)

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

    # 练习题
    strvar = "刘能和刘老根和刘铁柱子111子222"
    
    lst = re.findall("刘.",strvar) # ['刘能', '刘老', '刘铁']
    print(lst)
    
    lst = re.findall("刘.?",strvar) # ['刘能', '刘老', '刘铁']
    print(lst)
    
    lst = re.findall("刘.+",strvar) # ['刘能和刘老根和刘铁柱子111子222']
    print(lst)
    
    lst = re.findall("刘.*",strvar) # ['刘能和刘老根和刘铁柱子111子222']
    print(lst)
    
    lst = re.findall("刘.{4,}子",strvar) # ['刘能和刘老根和刘铁柱子111子']
    print(lst)
    
    # 非贪婪匹配
    lst = re.findall("刘.??",strvar) # ['刘', '刘', '刘']
    print(lst)
    
    lst = re.findall("刘.+?",strvar) # ['刘能', '刘老', '刘铁']
    print(lst)
    
    lst = re.findall("刘.*?",strvar) # ['刘', '刘', '刘']
    print(lst)
    
    lst = re.findall("刘.{4,}?子",strvar) # ['刘能和刘老根和刘铁柱子']
    print(lst)

    边界符

     本身也是转义字符 : 退格(把光标向左移动一位)
    word
    右边界: d
    左边界: w

    # 右边界
    strvar = "word pwd scf"
    lst = re.findall(r"d",strvar)
    print(lst) # ['d', 'd']
    
    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) # ['word pwd scf']
    
    lst = re.findall(r"w.*?",strvar)
    print(lst) # ['w']
    
    lst = re.findall(r"w.* ",strvar)
    print(lst) # ['word pwd ']
    
    lst = re.findall(r"w.*? ",strvar)
    print(lst) # ['word ']
    
    # S 匹配的是非空白符
    lst = re.findall(r"wS*",strvar)
    print(lst) # ['word']

    ^ $:开头/结尾

    ^ 匹配字符串的开始(必须以... 开头)
    $ 匹配字符串的结尾(必须以... 结尾)
    当使用^ 和 $ 符号的时候,要把字符串看成整体

    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('.*?_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']
    
    #  | 代表或 , a|b 匹配字符a 或者 匹配字符b . 把字符串长的写在前面,字符串短的写在后面
    strvar = "abcdefg"
    lst = re.findall("a|b",strvar)
    print(lst) # ['a', 'b']
    
    """在使用|的时候,把不容易匹配到的字符串放到前面,把容易匹配到的放到后面"""
    strvar = "abciuiuabcdwerewr"
    lst1 = re.findall("abc|abcd",strvar) # ['abc', 'abc']
    lst2 = re.findall("abcd|abc",strvar) # 把不容易匹配的放到前面 ['abc', 'abcd']
    print(lst1)
    print(lst2)

    匹配分组练习

    . 除了 ,匹配所有字符
    . 代表的.这个字符本身,不转义

    1.小数和整数

    strvar = ".34 .... 78.   78.12 56.3 .3 .4 .5 "
    # 匹配小数 
    lst = re.findall(r"d+.d+",strvar)
    print(lst)
    
    # 匹配小数和整数 
    lst = re.findall(r"d+.d+|d+",strvar)
    print(lst)
    
    # 分组来表达小数和整数
    lst = re.findall(r"d+(.d+)?",strvar)
    print(lst)
    
    lst = re.findall(r"d+(?:.d+)?",strvar)
    print(lst) # ['34', '78', '78.12', '56.3', '3', '4', '5']

    2.匹配135或171的手机号

    # 匹配135或171的手机号
    strvar = "13566668888 17166668888"
    lst = re.findall(r"(?:135|171)d{8}",strvar)
    print(lst) # ['13566668888', '17166668888']
    
    # 用^$卡死长度,只能是一个手机号,不能是多个
    strvar = "13566668888"
    lst = re.findall(r"^(?:135|171)d{8}$",strvar)
    print(lst) # ['13566668888']

    3.匹配www.baidu.com 或者 www.oldboy.com

    strvar = "www.baidu.com www.lagou.com www.oldboy.com"
    lst = re.findall(r"(?:www).(?:baidu|oldboy).(?:com)",strvar)
    print(lst)
    
    # search 的用法
    strvar = "www.baidu.com www.lagou.com www.oldboy.com"
    obj = re.search(r"www.(baidu|oldboy).(com)",strvar)
    
    # 返回的是匹配到的结果
    res = obj.group()
    print(res)
    
    # 通过group和下标可以获取到括号的内容(了解)
    print(obj.group(1))
    print(obj.group(2))
    
    # 返回的是括号分组里面的内容
    res = obj.groups()
    print(res)

    4.findall和search的区别

    1.findall 是把所有符合条件的内容都匹配出来放到列表里
    不能够把匹配到的结果和分组当中的内容显示在同一个界面当中
    2.search 按照正则表达式,把第一次匹配到的内容返回出来,返回的是对象
    能够把匹配到的结果和分组当中的内容显示在同一个界面当中
      对象.group 返回的是匹配到的结果
      对象.groups 返回的是括号分组里面的内容
      如果匹配不到内容,返回的是None ,无法调用group 或者groups方法的

    5."5*6-7/3" 匹配 5*6 或者 7/3 算出最后的结果

    strvar = "5*6-7/3"
    
    # 匹配5*6
    obj = re.search(r"d+[*/]d+",strvar)
    print(obj)
    strvar1 = obj.group()
    print(strvar1,type(strvar1),"<===>") # 5*6 <class 'str'> <===>
    
    # 计算5*6
    num1,num2 = strvar1.split("*")
    print(num1,num2)
    strvar2 = str(int(num1) * int(num2))
    print(strvar2 ,type(strvar2)) # "30"
    
    # 替换5*6 为字符串30
    strvar3 = strvar.replace(strvar1,strvar2)
    print(strvar3 , type(strvar3)) # 30-7/3 <class 'str'>
    
    # 匹配7/3
    obj = re.search(r"d+[*/]d+",strvar3)
    print(obj)
    strvar4 = obj.group()
    print(strvar4) # 7/3
    
    # 计算7/3
    num1,num2 = strvar4.split("/")
    strvar5 = str(int(num1) / int(num2))
    print(strvar5 , type(strvar5))
    
    # 替换7/3 为字符串2.333333333333
    strvar6 = strvar3.replace(strvar4,strvar5)
    print(strvar6 , type(strvar6))
    
    # 计算 30-2.3333333333333335 得出最后的结果
    num1,num2 = strvar6.split("-")
    res = float(num1) - float(num2)
    print(res)

    命名分组

    反向引用

    strvar = "<div> 今天天气不错~ </div>"
    lst = re.findall("<(.*?)>(.*?)<(.*?)>",strvar)
    print(lst) # [('div', ' 今天天气不错~ ', '/div')]
    
    # 反向引用 : 在匹配到的值,在引用一次
    '''1 把第一个小括号里面的内容,拿出来在匹配一下'''
    lst = re.findall(r"<(.*?)>(.*?)<(/1)>",strvar)
    print(lst) # [('div', ' 今天天气不错~ ', '/div')]
    
    # 1 代表反向引用第一个括号  2代表反向引用第二个括号
    strvar = "a1b2cab"
    # strvar = "f1z2pfz"
    obj = re.search(r"(.*?)d(.*?)d(.*?)12",strvar)
    print(obj) # <_sre.SRE_Match object; span=(0, 7), match='a1b2cab'>
    # 获取匹配到的内容
    res1 = obj.group()
    print(res1) # a1b2cab
    # 获取分组里面的内容
    res2 = obj.groups() 
    print(res2) # ('a', 'b', 'c')

    命名分组

    """
    (?P<组名>正则表达式) 给这个组起一个名字
    (?P=组名) 引用之前组的名字,把该组名匹配到的内容放到当前位置
    """
    
    # 方法一
    strvar = "a1b2cab"
    obj = re.search(r"(?P<tag1>.*?)d(?P<tag2>.*?)d(?P<tag3>.*?)12",strvar)
    # 获取匹配到的内容
    res1 = obj.group()
    print(res1)
    # 获取分组里面的内容
    res2 = obj.groups()
    print(res2)
    
    
    # 方法二
    strvar = "a1b2cab"
    obj = re.search(r"(?P<tag1>.*?)d(?P<tag2>.*?)d(?P<tag3>.*?)(?P=tag1)(?P=tag2)",strvar)
    # 获取匹配到的内容
    res1 = obj.group()
    print(res1)
    # 获取分组里面的内容
    res2 = obj.groups()
    print(res2)
  • 相关阅读:
    225. Implement Stack using Queues
    150. Evaluate Reverse Polish Notation
    159 Longest Substring with At Most Two Distinct Characters
    142. Linked List Cycle II
    打印沙漏 (20 分)
    人见人爱A-B
    人见人爱A+B
    杨辉三角
    进制转换
    汉字统计
  • 原文地址:https://www.cnblogs.com/libolun/p/13406708.html
Copyright © 2020-2023  润新知