Python的基础语法(十五)

1 认识正则表达式

  1. 什么是正则表达式

    正则表达式是一种可以让一些复杂字符串问题变得简单的工具。

    正则并不是Python特有的语法(不属于python),所有高阶语言都支持正则,正则语法通用。

    不管通过正则表达式解决的是什么问题,写正则的时候都是在使用正则表达式描述字符串规则。

    🍿判断指定的字符串是否是一个合法的手机号。

    11位,每一位都是数字,首位是1,第二位是3~9

    tel = input('请输入手机号:')
    
    
    # 方法一
    def is_tel(num: str):
        if len(num) != 11:
            return False
        for i in num:
            if not i.isdigit():
                return False
    
        if num[0] != '1':
            return False
        if '3' <= num[1] <= '9':
            return True
        return False
    
    
    print(is_tel(tel))
    
    
    # 方法二
    def is_tel2(num: str):
        from re import fullmatch
        return bool(fullmatch(r'1[3-9]\d{9}', num))
    
    
    print(is_tel2(tel))
    

    🍿提取字符串中所有的数字子串。

    str1 = '月薪: 25360元, 年龄18岁。身高:175,体重120斤。23'
    # ['25360', '18', '175', '120']
    
    # 方法一:
    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)
    
    # 方法二:
    from re import findall
    result = findall(r'\d+', str1)
    print(result)
    
  2. Python的re模块

    re模块是Python用来支持正则表达式的一个模块,模块中包含了所有和正则相关的函数。

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

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

    导入模块

    from re import fullmatch
    
  3. 正则语法

  • 匹配类符号

    符号说明
    普通符号在正则表达式中表示符号本身的符号
    .匹配任意一个字符
    \d匹配任意一个数字字符
    \s匹配任意一个空白字符
    \D匹配任意一个非数字字符
    \S匹配任意一个非空白字符
    [字符集]匹配字符集中的任意一个字符
    [ ^ 字符集]匹配不在字符集中的任意一个字符

    1)普通符号

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

    2).

    result = fullmatch(r'a.c', 'a.c')
    print(result)	#<re.Match object; span=(0, 3), match='a.c'>
    
    result = fullmatch(r'a.c', 'a+c')
    print(result)	#<re.Match object; span=(0, 3), match='a+c'>
    
    result = fullmatch(r'a..c', 'a*&c')
    print(result)	#<re.Match object; span=(0, 4), match='a*&c'>
    

    3)\d

    result = fullmatch(r'a\dc', 'a0c')
    print(result)	#<re.Match object; span=(0, 3), match='a0c'>
    

    4)\s

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

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

    5)\D

    result = fullmatch(r'a\Dc', 'a c')
    print(result)	#<re.Match object; span=(0, 3), match='a c'>
    
    result = fullmatch(r'a\Dc', 'a2c')
    print(result)	#None
    

    6)\S

    result = fullmatch(r'a\Sc', 'a2c')
    print(result)	#<re.Match object; span=(0, 3), match='a2c'>
    
    result = fullmatch(r'a\Sc', 'a\tc')
    print(result)	#None
    

    7)[字符集]

    result = fullmatch(r'zhou[and]shen', 'zhouashen')
    print(result)	#<re.Match object; span=(0, 9), match='zhouashen'>
    
    result = fullmatch(r'[\u4e00-\u9fa5]', '哈')
    print(result)	#<re.Match object; span=(0, 1), match='哈'>
    

    []中减号放在两个字符之间表示谁到谁(确定的方式是根据字符编码值大小确定的);如果减号不在两个字符之间,就表示一个普通的减号。

    🌰栗子:

    [abc]:匹配a或者b或者c

    [abc\d]、[c\dba]:匹配a或者b或者c或者任意一个数字

    [2-8]:匹配2到8中任意一个数字(前者的编码值小于后者)

    [a-z]:匹配任意一个小写字母

    [a-zA-Z]、[A-Za-z]:匹配任意一个字母

    [a-zA-Z\d_]:匹配字母数字下划线

    [\u4e00-\u9fa5]:匹配任意一个中文字符

    8)[ ^ 字符集]

    ^在最前面。

    result = fullmatch(r'[^\u4e00-\u9fa5]', '哈')
    print(result)	#None
    
  • 匹配次数

    符号说明
    *0次或多次(任意次数)
    +1次或者多次(至少一次)
    0次或1次
    {M,N}M到N次
    {M,}至少M次
    {,N}最多N次
    {N}N次

    1)*

    注意:*在谁的后面控制的就是谁的次数。

    匹配符号*
    
    result = fullmatch(r'a*11', 'aaa11')
    print(result)	#<re.Match object; span=(0, 5), match='aaa11'>
    
    result = fullmatch(r'[ab]*11', 'abbaa11')
    print(result)	#<re.Match object; span=(0, 7), match='abbaa11'>
    

    2)+

    result = fullmatch(r'[ab]+11', '11')
    print(result)	#None
    
    result = fullmatch(r'[ab]+11', 'b11')
    print(result)	#<re.Match object; span=(0, 3), match='b11'>
    

    3)?

    result = fullmatch(r'a?11', 'aa11')
    print(result)	#None
    

    4){}

    result = fullmatch(r'zs{3}', 'zsss')
    print(result)	#<re.Match object; span=(0, 4), match='zsss'>
    
    result = fullmatch(r'zs{1,2}', 'zs')
    print(result)	#<re.Match object; span=(0, 2), match='zs'>
    
    result = fullmatch(r'zs{3,}', 'zssss')
    print(result)	#<re.Match object; span=(0, 5), match='zssss'>
    
    result = fullmatch(r'zs{2,}', 'zss')
    print(result)	#<re.Match object; span=(0, 3), match='zss'>
    

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

    qq = '123204832'
    result = fullmatch(r'[1-9]\d{4,11}', qq)
    if result:
        print('合法')
    else:
        print('不合法')
    

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

    str1 = '_csdw2dhj'
    result = fullmatch(r'[a-zA-Z_][a-zA-Z_\d]*', str1)
    if result:
        print('合法')
    else:
        print('不合法')
    

2 贪婪和非贪婪

当匹配次数不确定的时候(*、+、?、{M,N}、{M,}、{,N}),匹配模式分为贪婪和非贪婪,默认是贪婪的。

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

    贪婪模式:*、+、?、{M,N}、{M,}、{,N}

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

    非贪婪模式:*?、+?、??、{M,N}?、{M,}?、{,N}?

    match(正则表达式,字符串)	判断字符串开头是否符合正则表达式描述的规则
    
    from re import match
    
    # 贪婪模式
    result = match(r'a.+b', 'amb计算bxxbmn')
    print(result)           # <re.Match object; span=(0, 9), match='amb计算bxxb'>
    
    # 非贪婪模式
    result = match(r'a.+?b', 'amb计算bxxbmn')
    print(result)           # <re.Match object; span=(0, 3), match='amb'>
    
    # 注意:如果匹配结果只有一种可能,那么贪婪和非贪婪的结果一样
    result = match(r'a.+b', 'ambxx')
    print(result)           #  <re.Match object; span=(0, 3), match='amb'>
    
    result = match(r'a.+?b', 'ambxx')
    print(result)           # <re.Match object; span=(0, 3), match='amb'>
    

    注意:如果匹配结果只有一种可能,那么贪婪和非贪婪的结果一样。

3 分组和分支

  1. 分组()

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

    result=fullmatch(r'(\d\d[A-Z]{2})+','23HJ')
    print(result)	#<re.Match object; span=(0, 4), match='23HJ'>
    

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

    result = fullmatch(r'(\d{2})[A-Z]\1', '23H03')
    print(result)	#None
    
    result = fullmatch(r'(\d{2})[A-Z]\1', '23H23')
    print(result)	#<re.Match object; span=(0, 5), match='23H23'>
    
    result = fullmatch(r'(\d{2})([A-Z]{2})=\2\1', '23ED=ED23')
    print(result)	#<re.Match object; span=(0, 9), match='23ED=ED23'>
    

    注意:\M只能重复在它之前出现的内容,不能重复在它之后出现的内容。

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

    🧈提取message中金额对应的数字子串。

    from re import findall
    
    message = '我今年18岁,月薪500000元,交300元腾讯会员费,放贷2000元。'
    result = findall(r'(\d+)元', message)
    print(result)	#['500000', '300', '2000']
    
  2. 分支|

    正则1|正则2|正则3|... 匹配可以和多个正则中任意一个正则匹配的字符串。
    

    🧈匹配一个字符串是三个数字或者两个小写字母。

    result = fullmatch(r'\d{3}|[a-z]{2}', '323')
    print(result)	#<re.Match object; span=(0, 3), match='323'>
    
    result = fullmatch(r'a(\d{3}|[a-z]{2})b', 'a323b')
    print(result)	#<re.Match object; span=(0, 5), match='a323b'>
    

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

4 转义符号

  1. 转义符号

    正则中的转义符号,就是本身具备特殊功能或者特殊意义的符号前加’',让这个符号变成一个普通符号。

    result = fullmatch(r'\d\+\d=\d', '1+2=3')
    print(result)	#<re.Match object; span=(0, 5), match='1+2=3'>
    
    result = fullmatch(r'\\d\+\\d=d{2}', '\d+\d=dd')
    print(result)	#<re.Match object; span=(0, 8), match='\\d+\\d=dd'>
    
  2. []里面的转义符号

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

    result = fullmatch(r'\d[+]\d=\d', '1+2=3')
    print(result)	#<re.Match object; span=(0, 5), match='1+2=3'>
    

    本身在中括号中有特殊功能的符号,如果要表示普通符号必须加’'。

    result = fullmatch(r'a[MN-]b', 'a-b')
    result = fullmatch(r'a[M\-N]b', 'a-b')
    result = fullmatch(r'a[M^N]b', 'a^b')
    result = fullmatch(r'a[\^MN]b', 'a^b')
    

5 检测类符号

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

符号说明
\b检测是否是单词边界
\B检测是否不是单词边界
^检测是否是字符串开头
$检测是否是字符串结尾

单词边界:可以将两个单词分开或者区分开的符号都是单词边界。比如:空白符号、英文标点符号、字符串开头和字符串结尾。

result = fullmatch(r'abc\b mn', 'abc mn')
print(result)	#<re.Match object; span=(0, 6), match='abc mn'>

result = findall(r'\b\d+', message)
print(result)	#['929', '999']

result = findall(r'\B\d+', message)
print(result)	#['29', '1314', '929', '99']

result = findall(r'^\d+', message)
print(result)	#['929']

result = findall(r'^.{5}', message)
print(result)	#['929zs']

result = findall(r'.{5}$', message)
print(result)	#['球,999']

6 re模块常用函数

  1. 常用函数

    表达式说明
    fullmatch(正则表达式,字符串)完全匹配,判断整个字符串是否符合正则表达式描述的规则,匹配成功返回匹配对象,匹配失败返回空
    match(正则表达式,字符串)匹配字符串开头,判断字符串开头是否符合正则表达式描述的规则,匹配成功返回匹配对象,匹配失败返回空
    search(正则表达式,字符串)获取字符串中第一个能够和正则匹配成功的子串,能找到返回匹配对象,找不到返回空
    findall(正则表达式,字符串)获取字符串中所有满足正则的子串,返回一个列表,列表中的元素是字符串;注意:如果正则表达式中有分组,会针对分组做自动捕获(只获取分组匹配的结果)
    finditer(正则表达式,字符串)获取字符串中所有满足正则的子串,返回一个迭代器,迭代器中的元素是每个子串对应的匹配对象
    split(正则表达式,字符串)将字符串中所有满足正则的子串作为切割点对字符串进行切割
    sub(正则表达式,字符串1,字符串2)将字符串中所有满足正则的子串都替换成字符串1

    导入模块:

    from re import *
    
    result = fullmatch(r'\d{3}', '234')
    print(result)
    
    result = match(r'\d{3}', '823介绍数据库')
    print(result)
    
    result = search(r'\d{3}', 'ba203还是678说')
    print(result)
    
    result = findall(r'\d{3}', 'ba203还是678说kk0222jksn就是23311')
    print(result)
    
    result = finditer(r'\d{3}', 'ba203还是678说kk0222jksn就是23311')
    print(result)
    # print(next(result))
    print(list(result))
    
    str1 = '123aMKnb嗑生嗑死aKKssa923b==='
    # 将str1中的a和b作为切割点对字符串进行切割
    result = split(r'a|b', str1)
    print(result)       # ['123', 'MKn', '嗑生嗑死', 'KKss', '923', '===']
    
    result = sub(r'\d+', '+', 'ba203还是678说kk0222jksn就是23311')
    print(result)
    
  2. 匹配对象

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

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

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

    result = search(r'(\d{3})([A-Z]{2})', '-=2设计师234KM2239KH')
    print(result)       # <re.Match object; span=(6, 11), match='234KM'>
    print(result.group())       # '234KM'
    print(result.group(1))      # '234'
    print(result.group(2))      # 'KM'
    print(result.span())        # (6, 11)
    print(result.span(2)) 		#(9, 11)
    
  3. 参数

    1)匹配忽略大小写(?i)写在正则表达式最前面

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

    2)单行匹配(?s):匹配的时候.能和换行进行匹配

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

    result = fullmatch(r'abc.123', 'abc\n123')
    print(result)       # None
    
    result = fullmatch(r'(?s)abc.123', 'abc\n123')
    print(result)       # <re.Match object; span=(0, 7), match='abc\n123'>
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值