DAY16 正则表达式

DAY16 正则表达式

一. 认识正则表达式

正则表达式:解决字符串问题的工具(让复杂的字符串问题变成简单的一个工具)

在不同语言不同操作系统中通用

二. 匹配类符号

from re import fullmatch
2.1 re模块
  • re模块是python用来支持正则表达式的一个模块

    re模块中提供了各种和正则相关的函数:fullmatch, search,findall,match, splite,sub等等

  • fullmatch(正则表达式, 字符串) - 判断整个字符串是否完全符合正则表达式描述的规则,如果不符合返回值是None

  • python中提供正则表达式的方式:r’正则表达式’

    js中提供正则表达式的方式:/正则表达式/

2.2 匹配类符号 - 一个正则符号表示一类字符

匹配类符号在正则表达式中的作用:用来要求字符串中某个位置必须是什么样的字符

  1. 普通符号 - 在正则表达式中表示符号本身,对应字符串的要求就是符号本身
# 要求:总共有3个字符,第一个'a', 二'b',三'c'
result = fullmatch(r'abc', 'abc')
print(result)  # <re.Match object; span=(0, 3), match='abc'>

result = fullmatch(r'abc', 'acb')
print(result)   # None
  1. . - 匹配任意一个字符
# 要求字符串:总共有3个字符,第一个'a', 最后一个是'c',中间任意
result = fullmatch(r'a.c', 'a#c')
print(result)  # <re.Match object; span=(0, 3), match='a#c'>

result = fullmatch(r'..c', '四9c')
print(result)   # <re.Match object; span=(0, 3), match='四9c'>
  1. \d - 匹配一个任意数字

    \D - 匹配一个任意非数字

# 要求字符串:总共有3个字符,第一个'a', 最后一个是'c',中间任意数字
result = fullmatch(r'a\dc', 'a9c')
print(result)   # <re.Match object; span=(0, 3), match='a9c'>

result = fullmatch(r'\d\d\d', '194')
print(result)  # <re.Match object; span=(0, 3), match='194'>
  1. \s - 匹配任意一个空白字符

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

# 空白字符包括:空格,\n,\t
result = fullmatch(r'a\sb', 'a b')
print(result)

result = fullmatch(r'a\sb', 'a4b')
print(result)  # None
  1. \w - 匹配一个数字,字母或者下划线或者中文

    \W - 匹配一个非数字,字母或者下划线或者中文

result = fullmatch(r'a\wb', 'a4b')
print(result)
  1. \大写字母 - 与相应的小写字母的功能相反
  • \D - 匹配一个任意非数字

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

  • \W - 匹配一个非数字,字母或者下划线或者中文

  1. [字符集] - 匹配字符集中任意一个字符

注意:一个[]只能匹配一个字符

  • [多个普通符号] - eg[abc12]在a,b,c,1,2中任意一个可以匹配
  • [包含\开头的特殊符号] - eg[mn\d],[m\dn],[\dmn],要求是m或者n或者任意一个数字
  • [字符1(小)-字符2(大)] - eg[a-z],要求是任意一个小写字母
    [a-zA-Z],要求是任意一个字母
    [2-9a-z],要求2到9或者任意小写字母
    [\u4e00-\u9fa5],要求任意中文
    [\u4e00-\u9fa5\dabc],要求任意中文,任意数字,a, b
    注意:[]中如果-不在两个字符之间,就不能表示谁到谁,就全都在不同字符
result = fullmatch(r'a[xyz]b', 'axb')
print(result) # <re.Match object; span=(0, 3), match='axb'>

# 第二位可以匹配x,y,或者任意数字
result = fullmatch(r'a[xyz\d]b', 'a3b')
print(result)
  1. [^字符集] - 匹配不在字符集中的任意一个字符(^必须放最前面,否则就是普通字符)
result = fullmatch(r'a[^xyz\d]b', 'axb')
print(result) # None

三. 匹配次数

from re import fullmatch, search
  1. * - 匹配0次或者多次(任意次数)
  • a* - a出现任意次
  • \d* - 任意多个数字
  • [abc]* - 任意多个a或者b或者c
result = fullmatch(r'a*b', 'aaaab')
print(result)  # <re.Match object; span=(0, 5), match='aaaab'>
  1. + - 匹配1次或者多次(至少1次)
result = fullmatch(r'a+b', 'aaaab')
print(result)  # <re.Match object; span=(0, 5), match='aaaab'>
  1. ? - 0次或1次
result = fullmatch(r'-?b', '-b')
print(result)  # <re.Match object; span=(0, 2), match='-b'>
  1. {}
  • {N} - N次
    {M,N} - M到N次,[M,N]次(不要加空格)
    {M,} - 至少M次
    {,N} - 最多N次

  • * == {0,}
    + == {1,}
    ? == {0,1}

result = fullmatch(r'\d{3}b', '123b')
print(result)

result = fullmatch(r'\d{2,5}b', '123b')
print(result)
  1. 贪婪和非贪婪
  • 在匹配次数不确定的时候,匹配模式分为贪婪和非贪婪两种

    匹配次数不确定:*, +, ?, {M,N}, {M,},{,N}

  • 贪婪是在次数不确定的情况下,对应的字符串在不同次数下有多种匹配结果,贪婪取最多次数对应的结果(前提是匹配成功有多种情况)

    非贪婪取最少次数对应的结果

  • 贪婪:*,+, ?, {M,n}, {M,}, {,N}
    非贪婪:*?,+?, ??, {M,N}?, {M,}?, {,N}?

search(正则表达式,字符串) - 在字符串中查找第一个满足正则表达式的字符串

re_str = r'\d+'
result = fullmatch(re_str, '232432')
print(result)  # <re.Match object; span=(0, 6), match='232432'>, match='232432'贪婪

result = search(re_str, '幅度萨芬是232432')
print(result)   # <re.Match object; span=(5, 11), match='232432'>

re_str = r'\d+?'
result = fullmatch(re_str, '232432')
print(result)  # <re.Match object; span=(0, 6), match='232432'>

result = search(re_str, '幅度萨芬是232432')
print(result)  # <re.Match object; span=(5, 6), match='2'> match='2'非贪婪

# af发浮点数adsfsb     af发浮点数adsfsbaewab     af发浮点数adsfsbaewab艾弗森
result = search(r'a.*b', r'saf发浮点数adsfsbaewab艾弗森b03048')
print(result)  # <re.Match object; span=(1, 22), match='af发浮点数adsfsbaewab艾弗森b'>
result = search(r'a.*?b', r'saf发浮点数adsfsbaewab艾弗森b03048')
print(result)  # <re.Match object; span=(1, 13), match='af发浮点数adsfsb'>

四. 分组和分支

from re import fullmatch, findall
4.1 分组 - ()

分组就是在正则中用括号将正则中的部分内容括起来就形成了一个分组

  1. 整体操作
# 匹配:两个字母两个数字的结构重复3次,'mn78jh56lm89'
result = fullmatch(r'[a-zA-Z]{2}\d\d[a-zA-Z]{2}\d\d[a-zA-Z]{2}\d\d', 'mn78jh56lm89')
print(result)  # <re.Match object; span=(0, 12), match='mn78jh56lm89'>

result = fullmatch(r'([a-zA-Z]{2}\d\d){3}', 'mn78jh56lm89')
print(result)  # <re.Match object; span=(0, 12), match='mn78jh56lm89'>
  1. 重复

    在正则中:\N可以重复\N所在的位置的前面的第N个分组匹配的内容(左括号是第N个)

# 匹配:'23abc23'- Y '23abc56' - N
result = fullmatch(r'(\d\d)abc\1', '23abc23')
print(result) # <re.Match object; span=(0, 7), match='23abc23'>
  1. 捕获

    获取正则匹配结果中的部分内容

result = findall(r'\d\d', 'rwr23fsf435gd54g4gd=-2343;')
print(result)  # ['23', '43', '54', '23', '43']
result = findall(r'[a-z](\d\d)', 'rwr23fsf435gd54g4gd=-2343;')
print(result)  # ['23', '43', '54']
4.2 分支 - |

正则1|正则2 - 先用正则1进行匹配如果匹配成功就直接成功,如果匹配失败再用正则2进行匹配,如果匹配成功就成功,如果失败就失败

# 匹配:abc后面是两个任意数字或者两个任意的大写字母
result = fullmatch(r'abc(\d\d|[A-Z]{2})', 'abc23')

五. 检测类符号和转义字符

5.1 检验类符号

检测类符号不是匹配符号,不会要求某个位置必须是什么样的字符,而是用检测某个位置是否符号相关要求

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

单词边界 - 凡是可以用来将两个单词区分开的符号,例如:空白字符,标点符号,字符串开头,字符串结尾

ps: 匹配成功需要,正则表达式去掉\b后,字符串要满足要求;加上\b,在字符串对应位置也要符合要求

result = fullmatch(r'[a-z]{3}\b[a-z]{2}', 'mnshu')
print(result) # None
  1. \B - 检测是否是非单词边界

  2. ^ - 检测是否是字符串开头([]外面)

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

5.2 转义字符

正则中的转义符号是指本身就具备特殊功能的符号前加,让它本身具备的特殊功能消失变成一个普通符号

# 写一个正则匹配一个小数
result = fullmatch(r'\d+\.\d+', '2.3')
print(result)   # <re.Match object; span=(0, 3), match='2.3'>

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

补充:独立存在有特殊意义的符号,放到[]中特殊功能会直接消失变成一个普通符号,例如:+, *, ., ?, ) , (等

result = fullmatch(r'[.+*?$]ab[.]c', '+ab.c')
result = fullmatch(r'[.+*?$]ab\.c', '+ab.c')

六. re模块

import re
6.1 常用函数
  1. re.fullmatch(正则, 字符串) - 判断整个字符串是否能够和正则表达式匹配,如果匹配成功返回匹配对象,匹配失败返回None
result = re.fullmatch(r'\d{3}', '728')
  1. re.match(正则, 字符串) - 匹配字符串开头,如果匹配成功返回匹配对象,匹配失败返回None
result = re.match(r'\d{3}', '728福克斯过热而')
print(result)   # <re.Match object; span=(0, 3), match='728'>
  1. re.search(正则, 字符串) - 匹配字符串中第一个满足正则的子串,如果匹配成功返回匹配对象,匹配失败返回None
result = re.search(r'\d{3}', '728福克斯过热而')
print(result)   # <re.Match object; span=(0, 3), match='728'>
  1. re.findall(正则, 字符串) - 获取字符串中满足正则的子串,返回值是列表,列表中的元素是匹配到的字符串
result = re.findall(r'\d{3}', '728福克斯过s344热而565trdg')
print(result)  # ['728', '344', '565']
  1. re.findditer(正则, 字符串) - 获取字符串中所有满足正则的子串,返回一个迭代器,迭代器中的元素是匹配对象
result = re.finditer(r'\d{3}', '728福克斯过s344热而565trdg')
print(next(result))  # <re.Match object; span=(0, 3), match='728'>
  1. re.split(正则, 字符串, N) - 将字符串中所有满足正则表达式的字符串作为切割点对字符串进行切割,返回一个列表,列表中的元素是字符串
result = re.split(r'\d{3}', '728福克斯过s344热而565trdg')
print(result)  # ['', '福克斯过s', '热而', 'trdg']

result = re.split(r'\d{3}', '728福克斯过s344热而565trdg', 2)
print(result)  # ['', '福克斯过s', '热而565trdg']
  1. re.sub(正则, 字符串1, 字符串2, N) - 将字符串2所有满足正则的子串全部替换成字符串1
message = 'safhjsksjfsgqlagrkgh'
result = re.sub(r'[abc]', '++', message)
print(result)  # s++fhjsksjfsgql++grkgh
6.2 匹配对象
  1. 获取匹配结果对应的字符串

a.获取整个正则匹配到的字符串:匹配对象.group()

result = re.search(r'\d{3}', '728福克斯过s344热而565trdg')
print(result)  # <re.Match object; span=(0, 3), match='728'>

r1 = result.group()
print(r1)  # 728

b.获取某个分组匹配到的结果:匹配对象.group(N)

result = re.search(r'(\d{3})-([A-Z]{2})','方式718-SD 三个g564电话给')
print(result)   # <re.Match object; span=(2, 8), match='718-SD'>

r2 = result.group(1)
print(r2)       # 718
r3 = result.group(2)
print(r3)   # SD
  1. 获取匹配结果在原字符串中的位置信息
result = re.search(r'\d{3}', '728福克斯过s344热而565trdg')
print(result)  # <re.Match object; span=(0, 3), match='728'>

r1 = result.span()
print(r1)  # (0, 3)
6.3 参数
  1. 单行匹配和多行匹配
  • 多行匹配的时候,不能和’\n’进行匹配(默认)
  • 单行匹配的时候,能和’\n’进行匹配
result = re.fullmatch(r'a.c', 'a\nc')
print(result)  # None 多行匹配

# 设置单行匹配
result = re.fullmatch(r'a.c', 'a\nc', flags=re.S)
print(result)  # <re.Match object; span=(0, 3), match='a\nc'>

result = re.fullmatch(r'(?s)a.c', 'a\nc')
print(result)  # <re.Match object; span=(0, 3), match='a\nc'>
  1. 忽略大小写
默认情况下大写字母和小写不能匹配,忽略大小写以后大写字母就可以和对应小写字母匹配
result = re.fullmatch(r'abc', 'aBc')
print(result)   # None

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

result = re.fullmatch(r'(?i)abc', 'aBc')
print(result)   # <re.Match object; span=(0, 3), match='aBc'>
  1. 既忽略大小写又要单行匹配
# 方法1:flags=re.I|re.S
result = re.fullmatch(r'abc.12', 'aBc\n12', flags=re.S|re.I)
print(result)  # <re.Match object; span=(0, 6), match='aBc\n12'>
# 方法2:(?si)
result = re.fullmatch(r'(?si)abc.12', 'aBc\n12')
print(result)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值