zoukankan      html  css  js  c++  java
  • 正则表达式

    regex:正则表达式.匹配规则,是否满足规律.
    规则字符串.功能强大,通用性很强.
    作用:匹配(就是截取)和或查找符合某些规则的字符串.
    1.正则的作用:
    一种对数据的匹配.过滤/筛选逻辑的表达式

    match:表示从头开始匹配,如果一开始第一个字符没有匹配到,就返回None
    如果没有匹配到返回None
    记住:所有的正则加上r字符,一定保险
    保存有匹配结果的结果对象re.match(r'正则','数据')

    取出匹配结果 ---> 结果对象.group()
    如果没有成功匹配,返回None,成功:返回匹配的结果对象

    match函数的作用:从头开始匹配,如果匹配失败就返回None

    search():从头开始搜索,如果能够匹配,返回结果.如果匹配失败,就继续往后搜索并返回匹配结果,如果全部搜索完仍然没有匹配
    到,则最终返回None.


    比较:match():从头开始匹配,第一次匹配失败就不再往后,直接返回None
    search():全文搜索匹配,第一次匹配失败之后,继续往后搜索进行匹配.直到全文搜索完.

    import re
    
    res = re.match(r'world', 'hello world 123')
    res1 = re.search(r'world', 'hello world 123')
    print(res.group())  # 没有匹配到,直接报错 AttributeError: 'NoneType' object has no attribute 'group'
    print(res1.group())  # world
    
    """1. 匹配一个字符(元字符)"""
    
    # .点字符: 表示任意一个字符<
    换行符除外,
    换行,是一个字符,是转义的作用>
    print(len('
    '))  # 长度是1 说明一个字符
    print(re.search(r'叶问.', '叶问
    ').group())  # 也是没有匹配,直接报错,AttributeError: 'NoneType' object has no attribute 'group'
    print(re.search(r'叶问.', '叶问kk').group())  # 叶问k
    
    # []字符: 表示集合中的任意1个字符,注意格式:[字符],字符不需要加''引号,类似白名单的概念
    print(re.search(r'叶问[ABC123]', '叶问B').group())
    # [-]: -号和[]结合表示匹配字符的范围,例如:[A-Z] 匹配A字母到Z字母,[a-z]匹配小写字母
    # 范围:其实就是ASCII码的范围,例如可以[A-z]:表示A-z,即大小写均可以匹配.
    print(re.search(r'叶问[A-z]', '叶问z').group())
    # [^]:取反,禁止匹配集合中 的字符,类似黑名单.  例如[^数字]表示非数字,就是不要数字的意思,反选的意思.
    print(re.search(r'叶问[^A-z]', '叶问1').group())
    # --------------------------d数字占位符,w字符占位符,s,空白字符占位符----------------------------->
    # digit:数字
    # d 表示数字0-9,记住:是一个字符,等价于[0-9]
    # 匹配0-9,记住只能是匹配0-9之间的单个字符
    print(re.search(r'叶问[0-9]', '叶问5').group())
    print(re.search(r'叶问d', '叶问5').group())
    
    # D 匹配一个 非数字字符<任意>等价于[^0-9]
    print(re.search(r'叶问[^0-9]', '叶问#').group())
    print(re.search(r'叶问D', '叶问J').group())
    
    
    # space:空白
    # s: 空白字符 空格 换行
     tab缩进 	 
    vf 这些空白制表符,等价于[
    	
    vf]
    print(re.search(r'叶问sd', '叶问 9').group())
    print(re.search(r'叶问sssssd', '叶问 
    	
    vf9').group())
    
    print(re.search(r'叶问', '叶问 ').group())
    
    """
    用来设置单词界限。匹配单词(由字母数字或下划线组成的)的开始或结束(匹配开始时,单词之前不能有w;匹配结束时,
    单词之后不能有w)。写在表达式某个字符或字符串之前,表示此字符或字符串之前不能有w对应的字符;写在字符后面,
    表示此字符之后不能有w对应的字符。 所以可以只有一个放在字符前面或后面,也可以有2个(表示字符前后都不能有w对应的字符)。
    """
    
    # S:禁止匹配一个任意的空白字符  等价于 [^
    	
    vf]
    print(re.search(r'叶问sd', '叶问 9').group())
    print(re.search(r'叶问[^
    	
    vf]d', '叶问 9').group())
    
    # w: word 匹配一个 任意的 数字,字母,下划线 _  字符  等价于 [da-zA-Z_]
    print(re.search(r'叶问w', '叶问j').group())
    print(re.search(r'叶问[da-zA-Z_]', '叶问_').group())
    
    
    # W: 匹配一个任意的非数字,字母,_ 的字符,等价于 [^da-zA-Z_]
    print(re.search(r'叶问W', '叶问@').group())  # 叶问@
    print(re.search(r'叶问[^da-zA-Z_]', '叶问#').group())
    
    """匹配多个字符:需要次数的时候-量词"""
    # {数字}:表示数量,{3}表示3次
    # {n}:表示匹配n次,等价于{n,n}   {n,m}:表示至少n次,最多m次
    # 至少0次,至多100 --> {0,100} 这时候0可以不写,就是{,100}这种
    # 如果是无穷次数,则{,}
    print(re.search(r'叶问d{,}', '叶问133').group())
    
    
    # * :  就是0次和无穷次,等价于{,}或者{0,},也可以称之为任意多次
    # + : 至少一次,等价于 {1,}
    # ? : 0次或者1次 等价于{,1}或者{0,1}
    
    
    # 变量命名规则:字母,数字,下划线,不能以数字开头.
    print(re.search(r'[A-z_]w*', '_abc').group())
    print(re.search(r'[A-Za-z_]w*', '_abc').group())
    
    # qq号:第一位不是0,  位数在 5-11 位之间
    print(re.search(r'[1-9]d{4,10}', '12345678911222').group())
    
    
    # 匹配邮箱:w -->就表示一个字母/数字/_ 类型的字符.
    print(re.search(r'w{4,16}@qq.com', '2604244167@qq.com').group())
    print(re.search(r'w{4,16}@qq.com', '2604244167@qq.com.cn').group())
    
    """匹配开始位置和结束位置: ^ $"""
    # match() 可以不写^  与  search()结合^ 的作用类似
    # 开始位置 r'^xx字符' : 以xx字符开始
    # 结束位置 r'xx字符$' : 以xx字符结束
    # 开始,结束 r'^xxxxAA字符$' : 以x字符开始,以A字符结束
    # ^ 匹配的是开始位置,开始位置:前面没有任何字符了
    # $ 匹配结束位置,$后面没有任何字符,只能是结束位置
    # 匹配的是一个字符串,不是一个单一的字符.
    # 限制正则从第一个字符开始匹配,匹配到最后一个字符结束
    
    # 以字母,数字,下划线开始,位数是4-16位,以@qq.com结束的邮箱
    print(re.search(r'^w{4,16}.*m$', 'Q604244167$$$$$m').group())
    
    
    """匹配  分组 匿名分组 """
    # |  或者 ,匹配 | 左右两边任何一个表达式
    print(re.search(r'^w{4,16}@qq.com$|^w{4,16}@sina.com$', '2604244167@qq.com').group())
    
    # (|)  匹配()中|左右两边的任何一个表达式. 分组的意义:将数据从整体提取出来.     和[]不一样 []匹配单个字符, ()匹配一个字符串
    print(re.search(r'^w{4,16}@(qq|sina).com$', '2604244167@sina.com').group())
    print(re.search(r'^w{4,16}@(qq|sina).com$', '2604244167@qq.com').group())
    
    # 分组目的:将感兴趣的部分数据从整体中提取出来.
    # () 使用的时候,结合group(1),就是第一个分组,默认是0号分组,0号分组的默认情况是全部结果
    print(re.search(r'^(d{3,4})-(d{6,8})$', '0755-12345678').group(1))
    print(re.search(r'^(d{3,4})-(d{6,8})$', '0755-12345678').group(2))
    
    # 创建分组:r'(正则)'
    # .group()默认是.group(0) 表示0号分组,表示正则的整体匹配结果.
    # 如果有了() 分组,就写成 .group(1)表示 第一个分组,一个()就是一个分组
    data = '郑一峰:274667266@qq.com:683760w:15069065451:19870504'
    result = re.match(r'(.+):(.+):(.+):(d{11}):(d{8})', data)
    print(result.group(1, 2, 3, 4, 5))  # ('郑一峰', '274667266@qq.com', '683760w', '15069065451', '19870504')
    # 匿名分组
    """引用 匿名分组  分组: 分组编号 """
    # 引用分组  如果在后面的正则需要使用前面的分组数据.把前面匹配到的数据在后续使用的位置继续使用
    # r'() 分组编号' 记得在分组编号之前加空格
    
    print(re.search(r'^(d{3,4})-(d{6,8}) 1-2$', '0755-12345678 0755-12345678').group())
    # r的效果
    print(re.search('^(\d{3,4})-(\d{6,8}) \1-\2$', '010-12345678 010-12345678').group())
    
    """有名分组(命名分组):
    原因:(())里面出现(),乱了,无序了,所以这时候使用有名分组,匿名分组这个时候就不好
    使用了.不方便使用
     
     应用场景:分组数很多,分组引用会很复杂,修改正则中的分组会导致分组编号发生变化,分组引用就会失效,所以使用有名分组
     
     创建分组: r'(?P<分组别名>正则)'
     
     获取分组:结果对象.group('分组名字'),也可以使用序号
     """
    print(re.search(r'^(?P<quhao>d{3,4})-(d{6,8}) 1-2$', '0755-12345678 0755-12345678').group('quhao'))
    print(re.search(r'^(?P<quhao>d{3,4})-(d{6,8}) 1-2$', '0755-12345678 0755-12345678').group(1))
    """
    引用有名分组:(?P=分组名字)
    """
    print(re.search(r'^(?P<quhao>d{3,4})-(?P<zuoji>d{6,8}) (?P=quhao)-(?P=zuoji)$', '0755-12345678 0755-12345678').group(2))
    
    """re模块其他高级函数:"""
    
    
    
    """
    search(参数1,参数2):全文搜索,找到第一个就返回,返回值是结果对象
    match(参数1,参数2):从头,返回值是结果对象,自带^属性
        参数1:正则,参数2:数据
    
    findall():找到所有,返回所有值,且是一个列表格式.从数据中查找指定规则的所有数据,返回值是包含所有结果的列表
    
    
    sub(参数1,参数2,参数3,count = 参数4):将匹配的结果进行替换.
        把参数3中符合参数1规则的数据替换为参数2,替换次数为参数4.
        
        参数2不仅可以是一个字符串数据,还可以是一个函数名,会自动去找函数,并执行,将函数执行的返回值放到参数2的位置.
            
    split():按指定规则切割数据
    """
    def func(obj):
        data = re.match().group()
        print(data)
        return str(int(data) + 1)
    
    
    # re.sub(r's|<?w+>|&nbsp','','')
    
    """贪婪和非贪婪"""
    # .: 转义之后才能是.外面的r对.的转义无效,r只对的转义有效
    re.search(r'https://.+?.jpg', '')  # 找到第一个就返回
    re.findall(r'https://.+?.jpg', '')  # 找到所有,输出到一个列表
    
    """
    默认贪婪
    
    非贪婪:量词 {} + ? * 这些符号后面再加个?就是非贪婪
    
    相对概念:前提条件,能不能满足整体正则表达式匹配,尽量贪婪, 尽量懒惰
    
    """
    print(re.match(r'^(d+)(d{7})$', '12345678').group(1, 2))  # -->分成了2组
    print(re.match(r'^(d{3,4}?)(d{5})$', '12345678').group(1, 2))  # ('123', '45678')print(len('\1'))  # 2
    print(len(r'1'))  # 2 说明r的效果了.
    
    print(re.findall('\\', '\'))  # ['\']
    
    """
    r字符:对字符串中的自动加进行转义
    r'w' == '\w'
    如果需要匹配数据的\,正则需要使用\\
    """
  • 相关阅读:
    几种常用的曲线
    0188. Best Time to Buy and Sell Stock IV (H)
    0074. Search a 2D Matrix (M)
    0189. Rotate Array (E)
    0148. Sort List (M)
    0859. Buddy Strings (E)
    0316. Remove Duplicate Letters (M)
    0452. Minimum Number of Arrows to Burst Balloons (M)
    0449. Serialize and Deserialize BST (M)
    0704. Binary Search (E)
  • 原文地址:https://www.cnblogs.com/huaibin/p/12107265.html
Copyright © 2011-2022 走看看