8.9 正则

  1. 认识正则

    正则表达式是可以让复杂的字符串问题简单化的工具

    例:判断数字是否是电话号码

    方法一:之前学习的知识:

    tel = input('请输入手机号:')
    def is_tel(num:str):
        if len(num) != 11:
            return False
    
        for x in num:
            if not x.isdigit():
                return False
    
        if num[0] != '1':
            return False
    
        if '3' <= num[1] <= '9':
            return True
    
    
    print(is_tel(tel))
    

    方法二:使用正则:

    tel = input('请输入手机号:')
    def is_tel(num:str):
        from re import fullmatch
        return bool(fullmatch(r'1[3-9]\d{9}',num))
    
    
    print(is_tel(tel))
    

    例:提取字符串中的数字

    方法一:

    str1 = '月薪: 25360元, 年龄18岁。身高:175,体重120斤。23'
    result = []
    temp = ''
    for x in str1:
        if x.isdigit():
            temp += x
        else:
            if temp:
                result.append(temp)
                temp = ''
    
    if temp:
        result.append(temp)
    
    print(result)
    #['25360', '18', '175', '120', '23']
    

    方法二:

    str1 = '月薪: 25360元, 年龄18岁。身高:175,体重120斤。23'
    from re import findall
    result = findall(r'\d+', str1)
    print(result)
    #['25360', '18', '175', '120', '23']
    
  2. 什么是正则表达式

    正则并非python特有语法,也不属于python,所有高级语言都支持正则,语法通用

    不管解决什么问题,都是使用正则表达式描述字符串规则

  3. python的re模块

    python中用来支持正则表达式的模块,模块中包含了所有正则相关的函数

    其中函数

    fullmatch(正则表达式,字符串)

    判断正则表达式和指定的字符串是否完全匹配(判断整个字符串是否符合正则表达式所描述的规则)

    如果匹配成功返回匹配对象,匹配失败返回None

  4. 正则语法

    匹配类符号
    普通符号

    在正则表达式中表示符号本身的符号

    如:

    from re import fullmatch
    result = fullmatch(r'abc','abc')
    print(result)
    #<re.Match object; span=(0, 3), match='abc'>
    

    字符串的格式是‘abc’,如果输入的字符串是’abcd’就不匹配了

    特殊符号

    1).

    匹配任意一个字符

    如:

    from re import fullmatch
    result = fullmatch(r'a.c','a和c')
    print(result)
    #<re.Match object; span=(0, 3), match='a和c'>
    

    from re import fullmatch
    result = fullmatch(r'...ac','$$$ac')
    print(result)
    #<re.Match object; span=(0, 5), match='$$$ac'>
    

    2)\d

    匹配任意一个数字字符

    result = fullmatch(r’a\dc’,‘a1c’)

    print(result)

    则有0~9共十种情况

    3)\s

    匹配任意一个空白字符

    空白字符:能产生空白效果的字符,如:空格、换行、水平制表符

    4)\D

    匹配任意一个非数字字符

    5)\S

    匹配任意一个非空白字符

    6)[字符集]

    匹配字符集中的任意一个字符

    from re import fullmatch
    result = fullmatch(r'a[xyz]c','axc')
    
    print(result)
    #<re.Match object; span=(0, 3), match='axc'>
    

    只能是字符集中的一个字符,不能全部写或者多写

    [1-9] 表示1到9之间的任意一个数字

    [a-z]表示任意一个小写字母

    [a-zA-Z]表示任意一个字母

    [\u4e00-\u9fa5]任意一个中文

    7)[ ^字符集]

    匹配不在字符集中的任意一个字符

    匹配次数

    1)*

    0次或多次(任意次数)

    *控制的是其前面的符号的次数

    2)+

    1次或者多次(至少一次)

    3)?

    0次或1次

    4){}

    {m,n}表示m到n次

    {m,}至少m次

    {,n}最多n次

    {m}m次

    例:写一个正则,判断输入的内容是一个合法的QQ号(长度是5~12位的数字,第一位不能是0)

    from re import fullmatch
    qq = input('请输入一个账号:')
    result = fullmatch(r'[1-9]\d{4,11}', qq)
    if result:
        print(f'{qq} 合法')
    else:
        print(f'{qq} 不合法')
    

    例:判断输入的内容是否是一个合法的标识符(由字母、数字下划线组成,数字不能开头)

    str1 = 'abc'
    result = fullmatch(r'[a-zA-Z_][\da-zA-Z_]*', str1)
    print(result)
    #<re.Match object; span=(0, 3), match='abc'>
    
  5. 当匹配次数不确定的时候(贪婪模式:*,+,?,{m,n},{m,},{,n})匹配模式分为贪婪和非贪婪,默认是贪婪的

    贪婪:在匹配成功的时候有多种匹配结果,贪婪是最多次数对应的匹配结果(匹配次数不确定的地方,有多种匹配方式都可以匹配成功,贪婪取最多次数对应的结果,非贪婪取最少次数对应的结果)

    非贪婪模式:次数后面加上?(*?,+?,??,{m,n}?,{m,}?,{,n}?)

    如果匹配结果只有一种可能,贪婪和非贪婪的结果一致

  6. 分组和分支

    1. 分组 ()

      作用:

      1)整体:将正则表达式中的一部分作为一个整体进行相关操作

      2)重复:可以在正则表达式中通过 \M 来重复它前面的第M个分组的匹配结果

      例:

      from re import fullmatch
      result = fullmatch(r'(\d{2})([a-z]{3})=\2\1{3}','98xzy=xzy989898')
      print(result)
      #<re.Match object; span=(0, 15), match='98xzy=xzy989898'>
      

      3)捕获:只获取正则表达式中一部分匹配到的结果(分为自动捕获和手动捕获两种)

      例:只找出金额对应的数字

      from re import findall
      message = '我有五千元,18岁,身高188,房贷0元,给你的零花钱9999元'
      result = findall(r'(\d+)+元',message)
      print(result)
      #['0', '9999']
      
    2. 分支 |

      正则1|正则2|正则3|……

      作用:匹配可以和多个正则中任意一个正则匹配的字符串

      注意:想要正则表达式中的一部分实现多选一的效果,变化的部分用分组表示

      例:

      from re import fullmatch
      result = fullmatch(r'a\d{3}b|a[a-z]{2}b','a555b')
      print(result)
      #<re.Match object; span=(0, 5), match='a555b'>
      
  7. 转义符号

    在正则中,本身具有特殊功能或者特殊意义的符号前加 \ ,使其变成普通符号

    []里面的转义符号

    单独存在有特殊意义的符号(+、*、?、.等在[]中特殊意义会自动消失

    本身在[]中有特殊功能的符号,如果要表示普通符号必须加 \

    例如-,放在两个字符之间就表示到的意义,想要表示减号的意义可以不放在字符之间、或者在前面加\

  8. 检测类符号

    是在匹配成功的情况下,检测检测类符号所在的位置是否符合相关要求

    1)\b

    检测是否是单词边界

    单词边界:可以将两个单词分开的符号都是单词边界

    如:空白符号、英文标点符号、字符串开头、字符串结尾

    from re import fullmatch
    message = 'abc78,55mm99,23abc,mm'
    result = findall(r'\d+\b',message)
    print(result)
    #['78', '99']
    #表示找出后面是单词边界的数字
    

    2)\B

    检测是否不是单词边界

    3)^

    检测是否是字符串开头

    from re import findall
    message = '56yyds,09,hh==kkk,00'
    result = findall(r'^.{2}',message)
    print(result)
    #['56']
    

    4)$

    检测是否是字符串结尾

  9. re模块

    常用函数

    1)fullmatch(正则表达式,字符串)

    完全匹配,判断整个字符串是否符合正则表达式描述的规则,匹配成功返回匹配对象,匹配失败返回空

    result = fullmatch(r'\d{3}', '234')
    print(result)
    #<re.Match object; span=(0, 3), match='234'>
    

    2)match(正则表达式,字符串)

    匹配字符串开头,判断字符串开头是否符合正则表达式描述的规则,匹配成功返回匹配对象,匹配失败返回空

    from re import match
    result = match(r'\d{3}', '823介绍数据库')
    print(result)
    #<re.Match object; span=(0, 3), match='823'>
    

    3)search(正则表达式,字符串)

    获取字符串中第一个能够和正则匹配成功的子串,能找到返回对象,否则返回空

    from re import search
    result = search(r'\d{3}', 'ba203还是678说')
    print(result)
    #<re.Match object; span=(2, 5), match='203'>
    

    4)findall(正则表达式,字符串)

    获取字符串中所有满足正则的子串,返回一个列表,列表中的元素是字符串。

    注意:如果正则表达式中有分组,会针对分组做自动捕获(只获取分组匹配到的结果)

    from re import findall
    result = findall(r'\d{3}', 'ba203还是678说kk0222jksn就是23311')
    print(result)
    #['203', '678', '022', '233']
    

    5)finditer(正则表达式,字符串)

    获取字符串中所有满足正则的子串,返回一个迭代器,迭代器中的元素是每个子串对应的匹配对象

    from re import finditer
    result = finditer(r'\d{3}', 'ba203还是678说kk0222jksn就是23311')
    print(result)
    # print(next(result))
    print(list(result))
    #<callable_iterator object at 0x00000181893125E0>
    [<re.Match object; span=(2, 5), match='203'>, <re.Match object; span=(7, 10), match='678'>, <re.Match object; span=(13, 16), match='022'>, <re.Match object; span=(23, 26), match='233'>]
    

    6)split(正则表达式,字符串)

    将字符串中所有满足正则的子串作为切割点对字符串进行切割

    from re import split
    str1 = '123aMKnb嗑生嗑死aKKssa923b==='
    # 将str1中的a和b作为切割点对字符串进行切割
    result = split(r'a|b', str1)
    print(result)
    # ['123', 'MKn', '嗑生嗑死', 'KKss', '923', '===']
    

    7)sub(正则表达式,字符串1,字符串2)

    将字符串2中所有满足正则的子串都替换成字符串1

    from re import sub
    result = sub(r'\d+', '+', 'ba203还是678说kk0222jksn就是23311')
    print(result)
    #ba+还是+说kk+jksn就是+
    
    匹配对象

    例:

    from re import search
    result = search(r'(\d{3})([A-Z]{2})', '-=2设计师234KM222哈哈宿舍239KH')
    print(result)
    # <re.Match object; span=(6, 11), match='234KM'>
    

    1)直接获取整个正则表达式对应的匹配结果:匹配对象.group()

    from re import search
    result = search(r'(\d{3})([A-Z]{2})', '-=2设计师234KM222哈哈宿舍239KH')
    print(result.group())
    #234KM
    

    2)手动捕获某个分组对应的匹配结果:匹配对象.group(分组数)

    from re import search
    result = search(r'(\d{3})([A-Z]{2})', '-=2设计师234KM222哈哈宿舍239KH')
    print(result.group(1))
    print(result.group(2))
    #234
    #KM
    

    3)获取匹配结果在元字符串中的位置:匹配对象.span()

    from re import search
    result = search(r'(\d{3})([A-Z]{2})', '-=2设计师234KM222哈哈宿舍239KH')
    print(result.span(1))
    print(result.span(2))
    #(6, 9)
    #(9, 11)
    
    参数

    1)匹配忽略大小写:(?i)

    from re import fullmatch
    result = fullmatch(r'(?i)abc', 'AbC')
    print(result)
    #<re.Match object; span=(0, 3), match='AbC'>
    

    2)单行匹配(?s)

    多行匹配(默认):匹配的时候.不能和换行(\n)进行匹配

    from re import fullmatch
    result = fullmatch(r'abc.123', 'abc\n123')
    print(result)
    # None
    

    单行匹配:匹配的时候.可以和换行(\n)进行匹配

    from re import fullmatch
    result = fullmatch(r'(?s)abc.123', 'abc\n123')
    print(result)
    # <re.Match object; span=(0, 7), match='abc\n123'>
    #如果要进行匹配,需要将多行匹配转换成单行匹配
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值