day 14 ---- 正则表达式

day 14 ---- 正则表达式

1.认识正则表达式

1.)------ 一种可以让复杂的字符串问题变得简单的工具
  • 案例:

    # 案例1:判断输入的内容是否是一个合法的手机号码
    # 要求:a. 长度是11位、 b.全部都是数字字符  c. 第一位是1  d.第二位:3~9
    tel = '134893872n6'
    
    # 方法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('不合法')
    else:
        print('不合法')
    
    
    # 方法2:使用正则表达式
    from re import fullmatch
    result = fullmatch(r'1[3-9]\d{9}', tel)
    if result:
        print('合法')
    else:
        print('不合法')
    

    2.匹配类符号

1.)fullmatch函数
  • fullmatch(正则表达式,字符串)

  • 判断字符串是否满足正则表达式描述的规则,如果不满足,结果是None

    # 2.所有匹配类符号
    # 1)普通符号 - 在正则表达式中表示本身的字符就是普通符号
    result = fullmatch(r'abc', 'abc')
    print(result)
    
    # 2) . - 匹配任意一个字符
    result = fullmatch(r'.bc', '+bc')
    print(result)
    result = fullmatch(r'..bc','你好bc')
    print(result)
    # 3)  \d - 匹配任意一个数字字符
    result=fullmatch(r'a\d\db','a34b')
    # 4)\s  - 匹配任意一个空白字符
    # 空白字符  - 所有能产生空白效果的字符:空格、\t、\n
    result=fullmatch('a\sb','a b')
    print(result)
    # 5)\w  - 匹配任意一个数字、字母、下划线或者中文
    result=fullmatch(r'a\wb','a_b')
    print(result)
    # 6)\D、\S、\W
    """
    \后面跟大写字母对应的功能和\后面跟小写字母的功能相反
    \D - 匹配任意一个非数字字符
    """
    print(fullmatch(r'a\Ds\sc\we','awsac-e'))
    # 7)[字符集] - 匹配在字符集中任意一个字符
    """
    [amx]  - 匹配a、m、x中的任意一个
    [\dmn] - (\开头的特殊符号在中括号的还是有特殊意义)匹配任意一个数字或者m或者n
    [3-9mn] - (-在中括号中表示谁到谁)匹配3到9中的任意一个数字或者m或者n
    [a-z]   -   匹配任意一个小写字母
    [A-Z]   -   匹配任意一个大写字母
    [a-zA-Z]    -   匹配任意一个字母
    [\u4e00-\u9fa5]  - 匹配任意一个中文
    """ 
    print(fullmatch(r'a[abcd1]b','a1b'))
    
    result = fullmatch(r'a[ma\d]b', 'a3b')
    print(result)
    
    result = fullmatch(r'a[\u4e00-\u9fa5A-Z]b', 'aHb')
    print(result)
    
    # 注意:中括号中的-只有放在两个字符之间才能表示谁到谁,如果放在中括号的最前面或者最后面,或者放在中括号外面减号就只表示减号本身
    result = fullmatch(r'a[-A]b', 'a-b')
    print(result)
    
    result = fullmatch(r'a-z', 'a-z')
    print(result)
    
    # 8)[^字符集]  - 匹配不在字符集中的任意一个字符
    result = fullmatch(r'a[^A-Z]b', 'a9b')
    print(result)
    
    result = fullmatch(r'a[^mn]b', 'aLb')
    print(result)
    
    # 注意:[]里面的^,只有放在最前面才有特殊功能,如果不在最前面^就是普通符号
    result = fullmatch(r'a[s^A-Z]b', 'aMb')
    print(result)
    

3.匹配次数相关符号

# 1. *  -   0次或者多次(任意多次)
# 匹配类符号*
print(fullmatch(r'a*b', 'aaaaaaab'))
print(fullmatch(r'\d*b', '189761000b'))
print(fullmatch(r'.*b', 'ms23@b'))
print(fullmatch(r'[A-Z]*b', 'KSOASKb'))
# 2. +   -  1次或者多次
print(fullmatch(r'a+b', 'aaaaaab'))

# 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', 'aaab'))

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

贪婪:在能匹配成功的情况下有多种匹配次数,贪婪取次数最多的那个次数。 (+、*、?、{M,N}、{M,}、{,N})
非贪婪:在能匹配成功的情况下有多种匹配次数,非贪婪取次数最少的那个次数。(+?、*?、??、{M,N}?、{M,}?、{,N}?)
"""
print('---------------------------------------华丽的分割线------------------------------------')
# fullmatch(正则表达式, 字符串)  -  匹配整个字符串
# match(正则表达式, 字符串)  - 匹配字符串开头
print(match(r'a\db', 'a3b收拾收sjsksk'))

# 'a12b'、'a12b就是b'、'a12b就是b设b'
print(match(r'a.+b', 'a21b就是b设b计师'))         # <re.Match object; span=(0, 8), match='a21b就是b设b'>
print(match(r'a.+?b', 'a21b就是b设b计师'))        # <re.Match object; span=(0, 4), match='a21b'>

print(match(r'a.+b', 'a12b就是设计师'))          # <re.Match object; span=(0, 4), match='a12b'>
print(match(r'a.+?b', 'a12b就是设计师'))         # <re.Match object; span=(0, 4), match='a12b'>


# 练习:写正则表达式可以匹配任意一个整数字符串(不考虑0)
# 匹配成功:'123'、'9'、'-234'、'+233'
# 匹配失败:'23m'、'--7283'、'++782'、'009'、'02'
result = fullmatch(r'[+-]?[1-9]\d*', '123')
print(result)

4.分组和分支

# 1. () - 分组
"""
在正则表达式中可以用()将正则表达式中的部分内容括起来表示一个整体,一个()代表一个分组。
"""
# 1)整体控制 - 以某个部分为单位对符号进行控制
# 'mn123kl234hg092mn123'
print(fullmatch(r'([a-z]{2}\d{3})+', 'mn123kl234hg092'))

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

print(fullmatch(r'([a-z]{2})(\d{3})=\2\1{2}\2', 'mn891=891mnmn891'))

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

findall(正则表达式, 字符串)  -  获取字符串中所有满足正则的子串
"""
from re import findall
message = '年龄: 18岁, 身高: 170, 体重:120斤, 月薪:3000元, 房租:1000元'

result = findall(r'\d+', message)
print(result)       # ['18', '170', '120', '3000', '1000']

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

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

# b. 手动捕获  - 写额外的代码来获取匹配结果中分组匹配到的内容
result = fullmatch(r'(\d+)元', '8292元')
print(result)

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

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

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

print(result.group())       # 23ksk
print(result.group(1))      # 23
print(result.group(2))      # ksk


# 2. |  -  分支
"""
正则1|正则2  - 先用正则1去匹配,如果匹配成功整个正则表达式就匹配成功,如果匹配失败就用正则2来匹配。
"""

# '23mns'、'34看手机'
print(fullmatch(r'\d{2}[a-z]{3}|\d{2}[\u4e00-\u9fa5]{3}', '23klm'))
print(fullmatch(r'\d{2}([a-z]{3}|[\u4e00-\u9fa5]{3})', '23几十块'))

5.检测类符号

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

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

str1 = '123jsk5678换手机 789,89ksk890 数 899'
print(findall(r'\d+', str1))        # ['123', '5678', '789', '89', '890', '899']
print(findall(r'\b\d+', str1))      # ['123', '789', '89', '899']
print(findall(r'\d+\b', str1))      # ['789', '890', '899']
print(findall(r'\b\d+\b', str1))    # ['789', '899']


# 2. ^ - 检测是否是字符串开头
# 3. $ - 检测是否是字符串结尾
# search(正则, 字符串)  -  获取字符串中第一个满足条件的子串
print(search(r'\d{3}', 'sgg789几十739块'))
print(search(r'^1[3-9]\d{9}$', '13678992310'))

# 4.转义符号  - 在正则中有特殊意义的符号前加\,让这个符号变成普通符号
# '合.234'、'块.82902'
print(fullmatch(r'[\u4e00-\u9fa5]\.\d+', '和.233'))

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

# '(MHS)'、'(KLS)'
print(fullmatch(r'\([A-Z]{3}\)', '(HUK)'))


# 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 = '换手机2839就是就是09,hs78 728m开始 89'
result = findall(r'\d+', str1)
print(result)       # ['2839', '09', '78', '728', '89']

result = finditer(r'\d+', str1)
print(result)
print(next(result))     # <re.Match object; span=(3, 7), match='2839'>
print(list(result))

result = split(r'\d+', str1)
print(result)       # ['换手机', '就是就是', ',hs', ' ', 'm开始 ', '']

result = sub(r'\d+|[a-zA-Z]+', 'A', str1)
print(result)       # 换手机A就是就是A,hsA Am开始 A
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值