python 17 正则表达式

python 17 正则表达式

1. 认识正则

正则表达是一种可以让一些复杂的字符串问题变得简单的工具,绝大多数的语言都支持。

  • 举例:判断指定的字符串是不是一个合法的手机号11位;每一位都是数字;第一位必须是1;第二位必须是:3-9,
    • 用函数方法

      def is_tel(num:str):
          if len(num) != 11:
              return False
          if num[0] != '1':
              return False
          if  '3' <= num[1] <= '9':
              return True
          return False
      
      
      f=is_tel('1345677095')
      print(f)
      ##False
      
    • 用正则表达式

from re import fullmatch
tel=input('请输入电话号码')
result=fullmatch(r'1[3-9]\d{9}',tel)
print(result)
#结果显示
请输入电话号码13245678098
<re.Match object; span=(0, 11), match='13245678098'>
2. 匹配类符号
1. 什么是正则表达式?
  • 正则表达式是一种可以让复杂的字符串问题变得简单的工具。
  • 正则并不是python特有的语法(不属于python),所有的高级编程语言都支持正则,正则的语法通用。
  • 不管通过正则表达式解决的是什么问题,写正则的时候,都是在使用正则表达式描述字符串规则的。
2. python的re模块
  • re模块是python用来支持正则表达式的一个模块,模块中包含了所有和正则相关的函数。

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

      #导入fullmatch函数
      from re import fullmatch  
      
3. 正则语法
  • None表示匹配失败
1)普通符号 — 在正则表达式中表示符号本身的符号
from re import fullmatch
result=fullmatch(r'abd','abd')
print(result)
#<re.Match object; span=(0, 3), match='abd'>
2) . — 匹配任意一个字符
from re import fullmatch
result=fullmatch(r'a.c','aec')
print(result)
#<re.Match object; span=(0, 3), match='aec'>
3)\d — 匹配任意一个数字字符
from re import fullmatch
result=fullmatch(r'a\dc','a3c')
print(result)
# #<re.Match object; span=(0, 3), match='a3c'>
4) \s — 匹配任意一个空白字符,包括换行

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

from re import fullmatch
result=fullmatch(r'a\sc','a c')  #空格
print(result)
#<re.Match object; span=(0, 3), match='a c'>
from re import fullmatch
result=fullmatch(r'a\sc','a\tc')  #水平制表
print(result)
#<re.Match object; span=(0, 3), match='a\tc'>
5) \D — 匹配任意一个非数字字符
from re import fullmatch
result=fullmatch(r'a\Dc','a3c')
print(result)  #None
result1=fullmatch(r'a\Dc','a*c')
print(result1)
#<re.Match object; span=(0, 3), match='a*c'>
6) \S — 匹配任意一个非空白字符
from re import fullmatch
result=fullmatch(r'a\Sc','a c')
print(result) #None
result1=fullmatch(r'a\Sc','a!c')
print(result1)
#<re.Match object; span=(0, 3), match='a!c'>
7)[字符集] — 匹配字符集中的任意一个字符
from re import fullmatch
result=fullmatch(r'a[QWERTY]c','aRc')
print(result) 
#<re.Match object; span=(0, 3), match='aRc'>
  • [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] - 匹配任意一个中文字符

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

  • 示例

    from re import fullmatch
    result=fullmatch(r'wo[0-9]\slu','wo2 lu')
    print(result)  
    #<re.Match object; span=(0, 6), match='wo2 lu'>
    result=fullmatch(r'20220809[\u4e00-\u9fa5][\u4e00-\u9fa5]study','20220809好好study')
    print(result) 
    # <re.Match object; span=(0, 15), match='20220809好好study'>
    
8)[ ^字符集 ] — 匹配不在字符集中的任意一个字符(^要放在字符的最前面,最开头的位置,才会表示不取的意思)
from re import fullmatch
result=fullmatch(r'as[^QWER]','as')
print(result) #None
result1=fullmatch(r'as[^QWER]','as ')
print(result1) 
#<re.Match object; span=(0, 3), match='as '>
result2=fullmatch(r'as[^QWER]','asW')
print(result2)  #None
result3=fullmatch(r'as[^QWER]','asP')
print(result3)
#<re.Match object; span=(0, 3), match='asP'>
3. 匹配次数
1) * ---- 0次或者多次(任意次数)
  • 注意:*在谁的后面控制的就是谁的次数

  • 任意一个匹配符号*( * 放在谁的后面,谁就匹配多次),即a*表示0个或多个a

    from re import fullmatch
    result=fullmatch(r'as\d*Q[a-z]*T','as12QT')
    print(result)##前面可以是0个或多个数字,没有限制,Q前面是0个或多个字母。
    #<re.Match object; span=(0, 6), match='as12QT'>
    result=fullmatch(r'[MN]*SDF','MMMMMMSDF') #SDF前面0个或者多个MN
    print(result) #<re.Match object; span=(0, 9), match='MMMMMMSDF'>
    
2)+ ---- 1次或者多次(至少一次或者多次)
from re import fullmatch
result=fullmatch(r'a[MN]+\D+Qa','asQa')
print(result)  #None
result=fullmatch(r'a[MN]+\D+Qa','aMsQa') #[MN]里面的元素必须要至少有一次出现在后面的字符串中,\D表示只要不是数字的字符至少出现1次。
print(result) 
#<re.Match object; span=(0, 5), match='aMsQa'>
3)? — 0次或者1次
from re import fullmatch
result=fullmatch(r'[A-Z]?\d?OPOP','OPOP')#[A-Z]出现的匹配到的是0次或者1次,\d数字也是匹配到的次数0次或者1次
print(result)
#<re.Match object; span=(0, 4), match='OPOP'>
result1=fullmatch(r'[A-Z]?\d?OPOP','AOPOP')
print(result1) #<re.Match object; span=(0, 5), match='AOPOP'>
result2=fullmatch(r'[A-Z]?\d?OPOP','A12OPOP')
print(result2) #None 数字最多只能出现1次,出现两次就和正则表达式不匹配。
4 ) { } — 表示前面的那个字符出现的次数的范围是多少次
  • {M,N} - M次到N次

  • {M,} - 至少M次

  • {,N} - 最多N次

  • {N} - N次

    from re import fullmatch
    result=fullmatch(r'qwe{1,7}[2-7]\d{3}P','qwe666P')#[2-7]范围内的数没有匹配到一个
    print(result) #None
    from re import fullmatch
    result=fullmatch(r'qwe{1,7}[2-7]\d{3}A','qwe2679A')
    print(result)
    #<re.Match object; span=(0, 8), match='qwe2679A'>
    result=fullmatch(r'af[2,4]qw','af2qw')  #[2,4]表示2-4之间的一个数
    print(result)
    result=fullmatch(r'af{2,4}qw','afqw')
    print(result)  #None
    result=fullmatch(r'af{2,4}qw','affffqw')
    print(result) #<re.Match object; span=(0, 7), match='affffqw'>
    
    result=fullmatch(r'af{4}qw','affffqw')
    print(result)  #<re.Match object; span=(0, 7), match='affffqw'>
    
    • 练习:写一个正则,判断输入的内容是否是一个合法的QQ号(长度是5~12位的数字,第一位不能是0)

      from re import fullmatch
      num=input('请输入qq号:')
      result=fullmatch(r'[1-9]\d{5,12}',num)
      if result:
          print(f'{num}合法')
      else:
      	print(f'{num}不合法')
          
      #请输入qq号:12345
      # 12345不合法
      
    • 练习:判断输入的内容是否是一个合法的标识符(由字母、数字下划线组成,数字不能开头)

      str1=input('请输入标识符:')
      from re import fullmatch
      result=fullmatch(r'[a-zA-Z][a-zA-Z\d_]*',str1) #*表示0次或者多次
      print(result)
      #请输入标识符:1dc
      #None
      # 请输入标识符:a2
      # <re.Match object; span=(0, 2), match='a2'>
      
4. 贪婪和非贪婪
  • from re import match - 导入match函数

  • 语法:match(正则表达式,字符串) - 判断字符串开头是否符合正则表达式描述的规则。

    • fullmatch是匹配整个字符串,match是只匹配字符串的开头。

      from re import match
      result=match(r'[a-z]{3}\d','azx1qwe2sdf6')
      print(result)
      #<re.Match object; span=(0, 4), match='azx1'>
      

  • 贪婪和非贪婪

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

    • 贪婪:在匹配成功的时候有多种匹配结果,贪婪去最多次数对应的匹配结果,

      • 贪婪模式:*、+、?、{M,N}、{M},{N}
    • 非贪婪:在匹配成功的时候有多种匹配结果,非贪婪取最少次数对应的匹配结果。

      • 非贪婪模式:*?、+?、??、{M,N}?、{M}?,{N}?
    • 匹配次数不确定的地方,有多种匹配方式都可以匹配成功,贪婪取最多次数, 非贪婪取最少次数。

    • 示例

      #贪婪模式
      from re import match
      result=match(r'\d{3}.+的','123斤斤的567计较军的123军军的234hhhh两的')
      print(result)
      #<re.Match object; span=(0, 28), match='123斤斤的567计较军的123军军的234hhhh两的'>
      #非贪婪模式
      result=match(r'\d{3}.+?的','123斤斤的567计较军的123军军的234hhhh两的')
      print(result)  
      #<re.Match object; span=(0, 6), match='123斤斤的'>
      
  • 注意:如果匹配结果只有一种可能,那么贪婪和非贪婪的结果一样。

    result=match(r'a.+b','amb')
    print(result)  ##<re.Match object; span=(0, 3), match='amb'>
    #非贪婪模式
    result=match(r'a.+?b','amb')
    print(result)    #<re.Match object; span=(0, 3), match='amb'>
    
5. 分组和分支
1) 分组 - ( )(括号把正则的一部分内容用括号括起来,表示一个组)
  • 整体 - 将正则表达式中的一部分作为一个整体进行相关操作

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

    • 注意:\M只能重复在它之前的分组的内容,无法重复在它之后出现的内容。

      from re import fullmatch,findall
      result=fullmatch(r'(\d{2})\1\2=([a-z]{2})','2323mk=mk')
      # print(result)  #报错re.error: invalid group reference 2 at position 10
      
  • 捕获 - 只获取正则表达式中分组匹配到的结果(分为手动捕获和自动捕获两种)使用函数findall,返回的结果是一个列表

    #整体
    from re import fullmatch,findall
    result=fullmatch(r'(\d[a-z][A-Z]\D)+','1sE*1sE*')
    print(result)
    #<re.Match object; span=(0, 8), match='1sE*1sE*'>
    #重复
    result=fullmatch(r'([a-zA-Z]{3})\d{2}\1','ASA66ASA')
    print(result)
    #<re.Match object; span=(0, 8), match='ASA66ASA'>
    #捕获
    message='小明今年13岁,电话号码是:13465434567,身高189cm,妈妈给了小明1000元的生活费,小明30天花了850元,还剩150元,剩下的150元小明用来给妈妈买衣服'
    result=findall(r'(\d+)元',message) #这里的括号就是对金额的捕获,如果不加(),得出的结果就是金额+元。
    print(result)
    #['1000', '850', '150', '150']
    result1=findall(r'\d+元',message)
    print(result1)
    #['1000元', '850元', '150元', '150元']
    
2) 分支 :

格式:正则1 | 正则2 | 正则3 | 正则4··· - 匹配可以和多个正则中任意一个匹配的字符串。

from re import fullmatch
result=fullmatch(r'\d([a-z]{2}q|2[A-Z]{2,6}hi|[\u4e00-\u9f5a]{3})\d','7明天见3')
print(result)
#<re.Match object; span=(0, 5), match='7明天见3'>

##其他例子
result=fullmatch(r'\d{3}|[a-z]{2}','mk')
print(result)  
#<re.Match object; span=(0, 2), match='mk'>

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

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

result=fullmatch(r'a([a-z]{3}|\d{4})b','a2345b')
print(result)  
#<re.Match object; span=(0, 6), match='a2345b'>
  • 注意:如果想要正则表达式中的一部分实现多选一的效果,变化的部分用分组表示
6. 转义字符
1)转义符号

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

#匹配任意一个小数对应的字符串
result=fullmatch(r'\d+\.\d+','23.3456')
print(result) 
#<re.Match object; span=(0, 7), match='23.3456'>
result=fullmatch(r'\d+.\d+','23.3456')
print(result)  
#<re.Match object; span=(0, 7), match='23.3456'>
result=fullmatch(r'\d+.\d+','2303456')
print(result) 
#<re.Match object; span=(0, 7), match='2303456'>

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

#(mv)、(ksma)
result=fullmatch(r'\([a-z]+\)','(sdfvfvf)')
print(result)   
#<re.Match object; span=(0, 9), match='(sdfvfvf)'>

result=fullmatch(r'\{[0-9]{4,8}\}','{24696}')
print(result)  
#<re.Match object; span=(0, 7), match='{24696}'>

result=fullmatch(r'\{[\u4e00-\u9fa5]{3,9}\}','{快乐星球}')
print(result)  
#<re.Match object; span=(0, 6), match='{快乐星球}'>

result = fullmatch(r'\\\d+', '\92233')
print(result)
#<re.Match object; span=(0, 6), match='\\92233'>
2) [ ] 里面的转义符号

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

result=fullmatch(r'\d+[+*?]\d+','1234+34')
print(result)  #<re.Match object; span=(0, 7), match='1234+34'>

result=fullmatch(r'a[MN-]b','aMb')
print(result) #<re.Match object; span=(0, 3), match='aMb'>
result=fullmatch(r'a[MN-]b','a-b') #这里的-表示M到N
print(result)  #<re.Match object; span=(0, 3), match='a-b'>
result=fullmatch(r'a[M-N]b','aMb') #这里的-表示M到N
print(result) # <re.Match object; span=(0, 3), match='aMb'>
result=fullmatch(r'a[M\-N]b','a-b') #这里的-表示M到N
print(result) #<re.Match object; span=(0, 3), match='a-b'>

result=fullmatch(r'a[MN^]',)
result=fullmatch(r'a[\\dMN]\d+','a\d1234567')
print(result)
7. 检测类符号(了解)

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

  • \b - 检测是否是单词边界

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

      result = fullmatch(r'abc\b mn', 'abc mn')
      print(result)
      
      
      message = '203mn45,89 司机34kn;23;99mll==910,230 90='
      result = findall(r'\d+', message)
      print(result)       # ['203', '45', '89', '34', '23', '99', '910', '230', '90']
      
      result = findall(r'\d+\b', message)
      print(result)       # ['45', '89', '23', '910', '230', '90']
      
      result = findall(r'\b\d+', message)
      print(result)       # ['203', '89', '23', '99', '910', '230', '90']
      
      result = findall(r'\b\d+\b', message)
      print(result)       # ['89', '23', '910', '230', '90']
      
  • \B - 检测是否不是单词边界

    message = '203mn45,89 司机34kn;23;99mll==910,230 90='
    result = findall(r'\B\d+\B', message)
    print(result)
    
  • ^ - 检测是否是字符串开头

    message = '203mn45,89 司机34kn;23;99mll==910,230 90='
    result = findall(r'^\d+', message)
    print(result)
    #['203']
    #提取字符串前5个字符
    message = '203mn45,89 司机34kn;23;99mll==910,230 90='
    result = findall(r'^.{5}', message)
    print(result)
    #['203mn']
    
  • $ - 检测是否是字符串结尾

    # 提取字符串最后5个字符
    message = '203mn45,89 司机34kn;23;99mll==910,230 90='
    result = findall(r'.{5}$', message)
    print(result)
    # ['0 90=']
    
8. re模块常用函数
1) 常用函数
  • fullmatch(正则表达式, 字符串) - ----- 完全匹配,判断整个字符串是否符合正则表达式描述的规则,匹配成功返回匹配对象,匹配失败返回空.

    from re import *
    result = fullmatch(r'\d{3}', '234')
    print(result)
    #<re.Match object; span=(0, 3), match='234'>
    
  • match(正则表达式, 字符串) ---- 匹配字符串开头,判断字符串开头是否符合正则表达式描述的规则,匹配成功返回匹配对象,匹配失败返回空

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

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

  ```python
  result = search(r'\d{3}', 'ba203还是678说')
  print(result)
  #<re.Match object; span=(2, 5), match='203'>
  • findall(正则表达式, 字符串) - 获取字符串中所有满足正则的子串,返回一个列表,列表中的元素是字符串。

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

      result = findall(r'\d{3}', 'ba203还是678说kk0222jksn就是23311')
      print(result)
      #['203', '678', '022', '233']
      
  • finditer(正则表达式, 字符串) - 获取字符串中所有满足正则的子串,返回一个迭代器,迭代器中的元素是每个子串对应的匹配对象

    result = finditer(r'\d{3}', 'ba203还是678说kk0222jksn就是23311')
    print(result)
    #<callable_iterator object at 0x000001D28D2F1850>
    # print(next(result))
    print(list(result))
    #[<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'>]
    
  • split(正则表达式, 字符串) - 将字符串中所有满足正则的子串作为切割点对字符串进行切割.

    str1 = '123aMKnb嗑生嗑死aKKssa923b==='
    # 将str1中的a和b作为切割点对字符串进行切割
    result = split(r'a|b', str1)
    print(result)       
    # ['123', 'MKn', '嗑生嗑死', 'KKss', '923', '===']
    
  • sub(正则表达式, 字符串1, 字符串2) - 将字符串2中所有满足正则的子串都替换成字符串1

    result = sub(r'\d+', '+', 'ba203还是678说kk0222jksn就是23311')
    print(result)
    #ba+还是+说kk+jksn就是+
    
    message = '我草!你TM看不见吗?f u c k!'
    result = sub(r'(?i)草|TM|f\s*u\s*c\s*k|sb|妈', '*', message)
    print(result)
    #我*!你*看不见吗?*!
    
    
2) 匹配对象
  • 直接获取整个正则表达式对应的匹配结果: 匹配对象.group()

    result = search(r'(\d{3})([A-Z]{2})', '-=2设计师234KM222哈哈宿舍239KH')
    print(result)       # <re.Match object; span=(6, 11), match='234KM'>
    print(result.group())       # '234KM'
    
  • 手动捕获某个分组对应的匹配结果: 匹配对象.group(分组数)

    print(result.group(1))      # '234'
    print(result.group(2))      # 'KM'
    
  • 获取匹配结果在原字符串中的位置: 匹配对象.span()

print(result.span())            # (6, 11)
print(result.span(2))           # (9, 11)
3) 参数
  • 匹配忽略大小写: (?i)

    result = fullmatch(r'(?i)abc', 'AbC')
    print(result)
    #<re.Match object; span=(0, 3), match='AbC'>
    
  • 单行匹配: (?s) (了解!)

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

    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'>
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值