day14正则表达式

1.认识正则表达式
1.什么是正则表达式

一种可以让复杂的字符串问题变得简单的工具

# 案例1:判断输入的内容是否是合法的手机号码
# 要求:a.长度是11位 b.全部都是数字字符 c.第一位是1 d.第二位:3~9

tel = '13812174189'

# 方法1
if len(tel) == 11:
    if tel[0] == '1' and tel[1] in '3456789':
        flag = True
        for x in tel[2:]:
            if not '0' <= x <= '9':
                flag = False
                break
        if flag:
            print('合法')
    else:
        print('不合法')

else:
    print('不合法')

# 方法2:正则表达式
from re import fullmatch
result = fullmatch(r'1[3-9]\d{9}', tel)
if result:
    print('合法')
else:
    print('不合法')


# 案例2:提取字符串中所有的数字子串
message = '年龄:18岁, 身高: 178,  体重: 130斤'
# 方法1:
result = []
str1 = ''
for x in message:
    if '0' <= x <= '9':
        str1 += x
    else:
        if str1:
            result.append(str1)
        str1 = ''
if str1:
    result.append(str1)
print(result)

# 方法2:正则表达式
from re import findall
result = findall(r'\d+', message)
print(result)

2.匹配类符号
1. fullmatch函数
  • fullmatch(正则表达式, 字符串) - 判断字符串是否满足正则表达式描述的规则(如果不满足结果就是None)

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

2.所有匹配类符号
# 1)普通符号 - 在正则表达式中表示本身的字符就是普通符号
result = fullmatch(r'abc', 'abc')
print(result)

# 2).  - 匹配任意一个字符
result = fullmatch(r'.ab', '1ab')
print(result)

result = fullmatch(r'a..', 'a你好')
print(result)

result = fullmatch(r'.*a', '2da')
print(result)

# 3) \d  - 	匹配任意一个数字字符
result = fullmatch(r'a\d\db', 'a31b')
print(result)

# 4) \s  -  匹配任意一个空白字符
# 空白字符  - 所有能产生空白效果的字符:空格、 \t、\n
result = fullmatch(r'a\sb', 'a b')
print(result)

# 5) \w  - 匹配任意一个数字、字母、下划线或者中文
result = fullmatch(r'a\wb', 'a_b')
print(result)

# 6) \D、\S、\W
"""
\后面跟大写字母对应的功能和\后面小写字母的功能相反
\D - 匹配任意一个非数字字符
"""
result = fullmatch(r'a\Db\Sc\W', 'ajb2c*')
print(result)

# 7) [字符集] - 匹配在字符集中的任意一个字符
"""
[mad]  -  匹配m、a、d中的任意一个
[\dmn]  -  (\反斜杠开头的特殊符号还是有特殊意义)匹配任意一个数字或者m或者n
[3-9mn]  - (-在中括号中表示谁到谁)匹配3到9中的任意一个数字或者m或者n
[a-z]  -  匹配任意一个小写字母
[A-Z]  -  匹配任意一个大写字母
[a-zA-Z] - 匹配任意一个字母
[\u4e00-\u9fa5] - 匹配任意一个中文
"""
result = fullmatch(r'a[xyzr1]b', 'a1b')
print(result)

result = fullmatch(r'a[a\dc]b', 'a6b')
print(result)

result = fullmatch(r'a[\u4e00-\u9fa5A-Z]b', 'a好b')
print(result)

result = fullmatch(r'a[a-z\u4e00-\u9fa5A-Z1-9]\d\s\wsa','ab5\t_sa')
print(result)

# 注意:中括号中的-号放在两个字符之间才能表示谁到谁,如果放在中括号的前面或者最后面,或者放在中括号外面就是减号本身
result = fullmatch(r'a[-A]b', 'a-b')
print(result)

result = fullmatch(r'a-b', 'a-b')
print(result)

# 8)[^字符集] - 匹配不在字符集中的任意一个字符
result = fullmatch(r'a[^A-Z]b', 'a3b')
print(result)

result = fullmatch(r'a[^mn]b', 'acb')
print(result)

# 注意:[]里面的^,只有放在最前面才有特殊功能,如果不在最前面^就是普通符号
result = fullmatch(r'a[s^c]b','a^b')
print(result)

print(fullmatch(r'\w{4}-\w{3}|\w{4}', 'back-end'))
3.匹配次数相关符号

所有的次数相关的符号(*、+、?、{}都在需要控制次数符号的后面)

from re import fullmatch, match

# 1.*  - 0次或者多次(任意多次)
# 匹配类符号*
print(fullmatch(r'a*b', 'b'))
print(fullmatch(r'a*b', 'ab'))
print(fullmatch(r'a*b', 'aaaaab'))

print(fullmatch(r'\d*b', '12321546b'))
print(fullmatch(r'.*b', '1fdgsb'))
print(fullmatch(r'[A-Z]*b', 'ABCb'))


# 2.+  -  1次或者多次
print(fullmatch(r'a+b', 'b'))  # None
print(fullmatch(r'a+b', 'ab'))

# 3.?  - 0次或者1次
print(fullmatch(r'a?b', 'ab'))

# 4.{}  -  控制{}前面字符的次数
"""
{N}  - N次
{M,N}  -  M到N次
{M,}   -  至少M次
{,N}   -  最多N次
"""
print(fullmatch(r'a{3}b', 'aaab'))
print(fullmatch(r'a{3,5}b', 'aaaab'))
print(fullmatch(r'a{3,}b', 'aaaaaab'))
print(fullmatch(r'a{,3}b', 'aab'))


# 5.贪婪和非贪婪
"""
匹配次数不确定的时候匹配模式分为贪婪和非贪婪两种,默认是贪婪的。

贪婪:在能匹配成功的情况下,有多种匹配次数,贪婪取次数最多的那个次数。(+、*、?、{M,N}、{M,}、{,N})
非贪婪:在能匹配成功的情况下,有多种匹配次数,贪婪取次数最少的那个次数。(+?、*?、??、{M,N}?、{M,}?、{,N}?)

"""
# fullmatch(正则表达式, 字符串)  - 匹配整个字符串
# match(正则表达式, 字符串)  - 匹配字符串开头
print(match(r'a\db', 'a2b创建'))  # <re.Match object; span=(0, 3), match='a2b'>

# 'a21b'、 'a21b创b' 、'a21b创b建b'
print(match(r'a.+b', 'a21b创b建b'))  # <re.Match object; span=(0, 3), match='a21b创b建b'>
print(match(r'a.+?b', 'a21b创b建b'))  # <re.Match object; span=(0, 3), match='a21b'>

print(match(r'a.+b', 'a21b创建'))  # <re.Match object; span=(0, 3), match='a21b'>
print(match(r'a.+?b', 'a21b创建'))  # <re.Match object; span=(0, 3), match='a21b'>

print(match(r'a[a-z]{3,5}b', 'accdbdss'))  #

# 练习:写正则表达式可以匹配任意一个整数字符串
# 匹配成功:'123'、 '9' 、 '-234' 、 ’+359‘
# 匹配失败:'123m'、 '009' 、 '--234' 、 ’++359‘
str1 = '834'
result = fullmatch(r'[+-]?[1-9]\d*', str1)
print(result)

4.分组和分支
1. () - 分组
from re import fullmatch
"""
在正则表达式中可以用()将正则表达式中的部分内容括起来表示一个整体,一个()代表一个分组

"""

# 1)整体控制 - 以某个部分为单位对符号进行控制
# 'mn123kl234bl124mn988'
print(fullmatch(r'([a-z]{2}\d{3})+', 'mh124lk136'))

# 2)重复 - 在正则中可以通过\N来重复它前面第N个分组匹配到的结果
# '123-123'、 '001-001'、 '890-890'
print(fullmatch(r'(\d{3})-\1', '123-123'))

print(fullmatch(r'([a-z]{2})(\d{3})=\2\1{2}', 'ab123=123abab'))

print(fullmatch(r'(\w{2})(\d{3}[a-z]{1})=\1{2}\2', '1m123b=1m1m123b'))

# 3)捕获 - 获取匹配结果的某个部分
"""
捕获分为自动捕获和手动捕获两种,只有findall具有自动捕获的功能,其他情况需要手动捕获

findall(正则表达式, 字符串)  -  获取字符串中所有满足这正则的子串

"""
from re import findall
message = '年龄:18岁, 身高: 178,  体重: 130斤, 月薪:10000元'

result = findall(r'\d+', message)
print(result)   # ['18', '178', '130', '10000']

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

# 自动捕获 - 自动获取匹配结果分组匹配到的内容
result = findall(r'(\d+)元', message)
print(result)   # ['10000']

# 手动捕获 - 写额外的代码来获取匹配结果中分组匹配到内容
result = fullmatch(r'(\d+)元', '9782元')
print(result)  # <re.Match object; span=(0, 5), match='9782元'>

# 获取整个正则对应匹配结果:匹配对象.group()
print(result.group())   # 9782元

# 获取某个分组对应匹配结果:匹配对象.group(分组数)
print(result.group(1))   # 9782

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

print(result.group())   # 56han
print(result.group(1))  # 56
print(result.group(2))  # han
2. | - 分支
from re import fullmatch
"""
正则1|正则2  - 先用正则1去匹配,如果匹配成功整个正则表达式就匹配成功,如果匹配失败就用正则2去匹配。
"""

# '23mns' 、 '56打开它'
print(fullmatch(r'\d{2}[a-z]{3}|\d{2}[\u4e00-\u9fa5]{3}', '23mnc'))
print(fullmatch(r'\d{2}([a-z]{3}|[\u4e00-\u9fa5]{3})', '23开始的'))
5.检查类符号

检测类符号 - 在匹配成功的情况下,检测指定的位置是否符合相应的要求(不影响字符串长度)

1. \b - 检测\b所在的位置是否是单词边界
from re import fullmatch, findall
"""
单词边界:英文符号中可以区分出不同单词的符号(例如:空白符号、英文标点符号、字符串开头、字符串结尾)
"""
print(fullmatch(r'\d{2},\ba', '23,a'))  # <re.Match object; span=(0, 4), match='23,a'>

str1 = '132dah976安居客 999,832jd389 数据 955'
print(findall(r'\d+', str1))  # ['132', '976', '999', '832', '389', '955']
print(findall(r'\b\d+', str1))  # ['132', '999', '832', '955']
print(findall(r'\d+\b', str1))  # ['999', '389', '955']
print(findall(r'\b\d+\b', str1))  # ['999', '955']

2.^ - 检测是否是字符串开头 - 放到正则的最前面
3.$ - 检测是否是字符串结尾 - 放到正则的最后面
from re import  search
# search(正则, 字符串) - 获取字符串中第一个满足条件的子串
print(search(r'\d{3}', 'aohsu133简单前938看'))

# 实现了match的功能
print(search(r'^1[1-9]\d{9}$', '13898886890'))

# 实现了fullmatch的功能
print(search(r'^1[1-9]\d{9}', '13898886890额外'))
4.转义符号 - 在正则中有特殊意义的符号前加\,让这个符号变成普通符号
from re import fullmatch
# '和.2807'
print(fullmatch(r'[\u4e00-\u9fa5]\.\d+', '和.127'))

# '2*8'
print(fullmatch(r'\d\*\d', '3*3'))

# '(SHN)'
print(fullmatch(r'\([A-Z]{3}\)', '(HJL)'))
5. re模块 - 模块中和正则表达式相关的函数
from re import fullmatch, match, search, findall,finditer,sub, split
"""
fullmatch(正则, 字符串)  -   匹配整个字符串(判断整个字符串是否符合正则描述的规则),匹配成功返回匹配对象,匹配失败返回None
match(正则, 字符串)  -  匹配字符串开头(判断字符串开头是否符合正则描述的规则),匹配成功返回匹配对象,匹配失败返回None
search(正则, 字符串)  - 匹配字符串中第一个满足正则的子串,匹配成功返回匹配对象,匹配失败返回None
findall(正则, 字符串)  -  获取字符串中所有满足正则的子串,返回值是一个列表,列表中的元素是匹配到字符串
finditer(正则, 字符串)   -   获取字符串中所有满足正则的子串,返回值是一个迭代器,迭代器中的元素是匹配对象
split(正则, 字符串)  -   将字符串中所有满足正则的子串作为切割点对字符串进行切割
sub(正则, 字符串1, 字符串2)     -   将字符串2中所有满足正则的子串都替换成字符串1

"""
str1 = '案设计师抵抗力发388家218,182dh 90jda的决心'
result = findall(r'\d+', str1)
print(result)   # ['388', '218', '182', '90']

result = finditer(r'\d+', str1)
print(result)
print(next(result))
print(list(result))

result = split(r'\d+', str1)
print(result)

result = sub('r\d+|[a-zA-Z]+', 'A', str1)
print(result)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值