• day17 正则表达式+今日作业


    正则表达式

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

    8.1 匹配类符号

    1.什么是正则表达式

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

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

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

    2.python的re模块

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

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

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

    from re import fullmatch
    
    • 1

    3.正则语法 - 匹配类符号
    1)普通符号 - 在正则表达式中表示符号本身的符号

    result = fullmatch(r'abc','abc') #一般加r(文件导入导出时、正则表达式时加r)
    print(result.group()) #abc
    
    • 1
    • 2

    2). - 匹配任意一个字符

    result =fullmatch(r'a.c','abc')#只有中间有字符就行(包括有字或者无字)
    print(result.group()) #abc
    
    • 1
    • 2

    3)\d - 匹配任意一个数字字符

    result=fullmatch(r'a\dc','a6c')#只要中间是数字就匹配成功
    print(result.group()) #a6c
    
    • 1
    • 2

    4)\s - 匹配任意一个空白字符

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

    result = fullmatch(r'a\sc','a\nc') #只有能产生空白的字符就能匹配
    print(result.group())
    result = fullmatch(r'a\d\d\s.c','a11 1c')
    print(result.group()) #a11 1c
    
    • 1
    • 2
    • 3
    • 4

    5)\D - 匹配任意一个非数字的字符

    result = fullmatch(r'a\Dc','abc')#只有中间不是数字就能成功
    print(result.group()) #abc
    
    • 1
    • 2

    6)\S - 匹配任意一个非空白字符

    result = fullmatch(r'a\Sc','abc') #只有中间不是空白就能成功
    print(result.group()) #abc
    
    • 1
    • 2

    7)[字符集] - 匹配字符集中的任意一个字符

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

    [abc\d] - 匹配a或者b或者c或者任意一个数字(不在意顺序)

    [1-9] - 匹配1-9中的任意一个数字

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

    [A-Z] - 匹配任意一个大写字母

    [a-zA-Z] - 匹配任意一个字母

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

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

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

    的减号。

    result = fullmatch(r'a[MN\d]c','aMc')#后面中间的字符必须是[]里面任意一个字符
    result = fullmatch(r'a[a-z]c','abc')
    result = fullmatch(r'[1-9][a-z][A-Z][\u4e00-\u9fa5]','1aA张')
    print(result.group()) #1aA张
    
    • 1
    • 2
    • 3
    • 4

    8)[ ^字符集 ] - 匹配不在字符集中的任意一个字符(^放在开头表示不取后面的字符集,在中间就是普通字符)

    result = fullmatch(r'a[^MN]c','a1c')
    print(result.group()) #a1c
    
    • 1
    • 2

    8.2 贪婪和非贪婪

    from re import match
    
    • 1

    match(正则表达式,字符串) - 判断字符串开头是否是符号正则表达式描述的规则

    result =match(r'\d{3}','234cvb')
    print(result)
    
    • 1
    • 2

    1.贪婪和非贪婪 - 必须在有多种选择的情况下

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

    贪婪和非贪婪:在匹配成功的时候有多种匹配结果,贪婪取最多次数对应的匹配结果,非贪婪取最少次数对应的匹配结果

    (匹配次数不确定的地方有多种匹配方式都可以匹配成功,贪婪取最多次数,非贪婪取最少次数)

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

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

    1)贪婪模式

    result = match(r'a.+b','ambmnb123b')#amb ambmnb ambmnb123b(在多种次数,要最多次的)
    print(result)
    
    • 1
    • 2

    2)非贪婪模式

    result = match(r'a.+?b','ambmnb123b')#amb ambmnb ambmnb123b(在多种次数,要最小次的)
    print(result)
    # 注意:如果匹配结果只有一种情况,那么贪婪和非贪婪的结果一样
    
    • 1
    • 2
    • 3

    8.3 分组、分支、转义字符

    1.分组 - ()

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

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

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

    findall(正则表达式,字符串) - 获取字符串中所有的分组里面的东西

    from re import fullmatch,findall
    
    • 1

    整体

    # '12MN23SD23SD23DS...'
    result = fullmatch(r'(\d\d[A-Z]{2})+','21SD31AS21SA')#将需要重复的括起来
    print(result)
    
    • 1
    • 2
    • 3

    重复

    result = fullmatch(r'(\d{2})[a-z]\1\1','23m2323')#将某个位置和另外的一样,将需要重复的重复
    print(result)
    
    # 注意:\M只能重复在它之前的分组内容,无法重复在它之后的内容
    result = fullmatch(r'(\d{2})([a-z]{3})=\2\1','21mhi=mhi21')
    print(result)
    # result = fullmatch(r'(\d{2})\2\1=([a-z]{3})','21mhi=mhi21') 报错!!!
    result = fullmatch(r'(\d{3})(\s)([a-z])=\3\2\1','333 a=a 333')
    print(result)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    捕获

    # 提取金额对应的数字字串
    massage = '我今年18岁,月薪500000元,身高180,体重70公斤,8块腹肌,每月交300元的腾讯会员费,房贷每月3000元,车贷每月2200元'
    result = findall(r'(\d+)元',massage)#只会自动捕获分组里面的东西
    print(result) #['500000', '300', '3000', '2200']
    
    • 1
    • 2
    • 3
    • 4

    2.分支 - |(或者)

    正则1|正则2|正则3 - 匹配能满足多个正则中任意一个正则匹配的字符串

    result = fullmatch(r'\d{3}|[a-z]{2}','222')#字符串是3个数字或者2个字母就行
    print(result)
    
    # 注意:如果想正则表达式中的一部分实现多选一的效果,变化的部分用分组表示
    result = fullmatch(r'a(\d{3}|[a-z]{3})b','asdsb')
    print(result)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3.转义符号

    (1)正则中的转义符号就是在本身具备特殊功能或者特殊意义的符号前加“\”,让这个符号变成一个普通符号。

    # 匹配任意一个小数对应的字符串
    result = fullmatch(r'\d+\.\d+','23.12')#在具有特殊意义前面加\,可以让其变成普通字符,但是python中的就不是那是转义字符
    result = fullmatch(r'\+\d+','+152')
    result = fullmatch(r'{[a-z]+}','{a}')#{}前面可以不加\
    result = fullmatch(r'\([a-z]+\)','(asad)')#()前面两边都要加\
    print(result)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (2)[]里面的转义符号

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

    result = fullmatch(r'\d[.+*?]\d+','2.523')
    print(result)
    
    # 注意:本身在[]里面有特殊功能的符号,如果表示普通符号必须加"\"
    result = fullmatch(r'a[M\-N]b','a-b')
    result = fullmatch(r'a[MN-]b','a-b')
    result = fullmatch(r'a[\^MN]b','a^b')
    result = fullmatch(r'a[MN^]b','a^b')
    print(result)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    8.4 检测类符号

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

    1.\b -检测是否是单词边界

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

    result = fullmatch(r'abc\b mn','abc mn')
    print(result)
    message = '456tg67e w68e,34,43w ij;2ej;wi==90,23dhh'
    result = findall(r'\d+',message)
    print(result) #['456', '67', '68', '34', '43', '2', '90', '23']
    result = findall(r'\d+\b',message)
    print(result) #['34', '90']
    result = findall(r'\b\d+',message)
    print(result) #['456', '34', '43', '2', '90', '23']
    result = findall(r'\b\d+\b',message)
    print(result) #['34', '90']
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.\B - 是否不是单词边界

    message = '456tg67e w68e,34,43w ij;2ej;wi==90,23dhh'
    result = findall(r'\B\d+\B',message)
    print(result) #['56', '67', '68', '3', '3']
    
    • 1
    • 2
    • 3

    3.^ - 检测是否是字符串开头

    message = '456tg67e w68e,34,43w ij;2ej;wi==90,23dhh'
    result = findall(r'^\d+',message)
    print(result) #['456']
    # 提取字符串前5个
    result = findall(r'^.{5}',message)
    print(result)#['456tg']
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.$ - 检测是否是字符串结尾

    message = '456tg67e w68e,34,43w ij;2ej;wi==90,23dhh'
    result = findall(r'.{5}$',message)
    print(result) #['23dhh']
    
    • 1
    • 2
    • 3

    8.5 re模块常用函数

    from re import *
    
    • 1

    1.常用函数

    1) fullmatch(正则表达式, 字符串) - 完全匹配,判断整个字符串是否符合正则表达式描述的规则,匹配成功返回匹配对象,匹配

    失败返回空。

    result = fullmatch(r'\d{3}', '234')
    print(result)
    
    • 1
    • 2

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

    result = match(r'\d{3}', '823介绍数据库')
    print(result)
    
    • 1
    • 2

    3) search(正则表达式, 字符串) - 获取字符串中第一个能够和正则匹配的子串,能找到返回匹配对象,找不到返回空

    result = search(r'\d{3}', 'ba203还是678说')
    print(result)
    
    • 1
    • 2

    4) findall(正则表达式, 字符串) - 获取字符串中所有满足正则的子串,返回一个列表,列表中的元素是字符串。
    注意:如果正则表达式中有分组,会针对分组做自动捕获(只获取分组匹配到的结果)

    result = findall(r'\d{3}', 'ba203还是678说kk0222jksn就是23311')
    print(result)
    
    • 1
    • 2

    5) finditer(正则表达式, 字符串) - 获取字符串中所有满足正则的子串,返回一个迭代器,迭代器中的元素是每个子串对应的匹配对象

    result = finditer(r'\d{3}', 'ba203还是678说kk0222jksn就是23311')
    print(result)
    # print(next(result))
    print(list(result))
    
    • 1
    • 2
    • 3
    • 4

    6) split(正则表达式, 字符串) - 将字符串中所有满足正则的子串作为切割点对字符串进行切割

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

    7)sub(正则表达式, 字符串1, 字符串2) - 将字符串2中所有满足正则的子串都替换成字符串1

    result = sub(r'\d+', '+', 'ba203还是678说kk0222jksn就是23311')
    print(result)
    
    message = '我草!你TM看不见吗?f u c k!'
    result = sub(r'(?i)草|TM|f\s*u\s*c\s*k|sb|妈', '*', message)
    print(result)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.匹配对象

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

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

    print(result.group())       # '234KM'
    
    • 1

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

    print(result.group(1))      # '234'
    print(result.group(2))      # 'KM'
    
    • 1
    • 2

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

    print(result.span())            # (6, 11)
    print(result.span(2))           # (9, 11)
    
    • 1
    • 2

    3.参数
    1)匹配忽略大小写: (?i)

    result = fullmatch(r'(?i)abc', 'AbC')
    print(result)
    
    • 1
    • 2

    2)单行匹配: (?s) (了解!)

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

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

    result = fullmatch(r'abc.123', 'abc\n123')
    print(result)       # None
    
    result = fullmatch(r'(?s)abc.123', 'abc\n123')
    print(result)       # 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    今日作业

    利用正则表达式完成下面的操作:

    一、不定项选择题

    1. 能够完全匹配字符串"(010)-62661617"和字符串"01062661617"的正则表达式包括( )

      A. r"\(?\d{3}\)?-?\d{8}"
      B. r"[0-9()-]+"
      C. r"[0-9(-)]*\d*"
      D.r"[(]?\d*[)-]*\d*"

      解析:ABD

    2. 能够完全匹配字符串"back"和"back-end"的正则表达式包括( )
      A. r'\w{4}-\w{3}|\w{4}'
      B. r'\w{4}|\w{4}-\w{3}'
      C.r'\S+-\S+|\S+'
      D. r'\w*\b-\b\w*|\w*'

      解析:ABCD

    3. 能够完全匹配字符串"go go"和"kitty kitty",但不能完全匹配“go kitty”的正则表达式包括()
      A.r'\b(\w+)\b\s+\1\b'
      B. r'\w{2,5}\s*\1'
      C. r'(\S+) \s+\1'
      D. r'(\S{2,5})\s{1,}\1'

      解析:AD

    4. 能够在字符串中匹配"aab",而不能匹配"aaab"和"aaaab"的正则表达式包括( )
      A. r"a*?b"
      B. r"a{,2}b"
      C. r"aa??b"
      D. r"aaa??b"

      解析:BC

    二、编程题

    1.用户名匹配

    ​ 要求: 1.用户名只能包含数字 字母 下划线

    ​ 2.不能以数字开头

    ​ 3.⻓度在 6 到 16 位范围内

    user_name = 'fa21huh5617'
    result1 = fullmatch(r'[a-zA-Z_][0-9a-zA-Z_]{5,15}',user_name)
    print(result1)
    
    • 1
    • 2
    • 3
    1. 密码匹配

    ​ 要求: 1.不能包含!@#¥%^&*这些特殊符号

    ​ 2.必须以字母开头

    ​ 3.⻓度在 6 到 12 位范围内

    password = 'sdfdfdf'
    result2 = fullmatch(r'[a-zA-Z][^!@#¥%^&*]{5,11}',password)
    print(result2)
    
    • 1
    • 2
    • 3
    1. ipv4 格式的 ip 地址匹配
      提示: IP地址的范围是 0.0.0.0 - 255.255.255.255
    ipv4 = '100.21.21.52'
    result3 = fullmatch(r'(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))',ipv4)
    print(result3)
    
    • 1
    • 2
    • 3
    1. 提取用户输入数据中的数值 (数值包括正负数 还包括整数和小数在内) 并求和
    例如:“-3.14good87nice19bye” =====> -3.14 + 87 + 19 = 102.86
    
    • 1
    result4 = findall(r'[-\d.]+',num)
    sum1=sum(float(i) for i in result4)
    print(sum1)
    
    • 1
    • 2
    • 3
    1. 验证输入内容只能是汉字

      str1='洋洋'
      result5 = fullmatch(r'[\u4e00-\u9fa5]+',str1)
      print(result5)
      
      • 1
      • 2
      • 3
    2. 匹配整数或者小数(包括正数和负数)

      num1='857.266'
      result6 = findall(r'[-\d.]+',num1)
      print(result6)
      
      • 1
      • 2
      • 3
    3. 验证输入用户名和QQ号是否有效并给出对应的提示信息

      要求:
      用户名必须由字母、数字或下划线构成且长度在6~20个字符之间
      QQ号是5~12的数字且首位不能为0

      def verify():
          name = '32wew'
          QQ = '345678'
          if fullmatch(r'[0-9a-zA-Z]{6,20}',name)==None:
              print('用户名错误')
              if fullmatch(r'[1-9]\d{4,14}',QQ)==None:
                  print('密码错误')
              else:
                  return '验证成功'
      verify()
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    4. 拆分长字符串:将一首诗的中的每一句话分别取出来

      ​ poem = ‘窗前明月光,疑是地上霜。举头望明月,低头思故乡。’

    result8 = split(r',|。',poem)
    print(result8[:-1])
    
    • 1
    • 2
  • 相关阅读:
    分布式二级缓存组件实战(Redis+Caffeine实现)
    k8s遇到的错误记录
    雪花雪花雪花
    C++的封装、继承、多态
    12-MySQL性能监控与调优工具推荐
    视频监控系统/安防视频平台EasyCVR广场视频细节优化
    图像相似度对比分析软件,图像相似度计算方法
    国家统计局通用数据爬取思路+代码实现 (超级舒畅的一次爬取经历)
    Centos 7.6安装LXC
    driver.js 扩展下次“不再提示”功能
  • 原文地址:https://blog.csdn.net/qq_59778168/article/details/126255428