• 正则表达式


    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'
    如果需要匹配数据的\,正则需要使用\\
    """
  • 相关阅读:
    要学习编程?这10件事情你知道了吗?
    JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Python创建者Van Rossum等编程大牛对程序员的职业建议
    这8个免费的网上课程可以有助你的技术成长
    给游戏开发初学者的10条建议
    21个国外受欢迎的学习编程的网站:总有一个理由会让你爱上它们
    hibernate 知识梳理
    struts2 知识梳理
    maven 相关
    c#配置log4net步骤
    arcobject 相关
  • 原文地址:https://www.cnblogs.com/huaibin/p/12107265.html
Copyright © 2020-2023  润新知