Pyf20230328(Python正则表达式)

01 什么是正则

1.正则的作用

正则表达式是一种可以让复杂的字符串变得简单的工具
写正则表达式的时候就是用正则符号来描述字符串规则
先加载re模块

import re
例1:判断一个字符串是否是一个合法的电话号码
tel = '18613213264'
# 方法1不用正则
if len(tel) == 11:
    if tel[0] == '1':
        if tel[1] in '3456789':
            if tel[2: ].isdigit():
                print( '合法')
            else:
                print('不合法')
        else:
            print( '不合法')
    else:
        print( '不合法')
else:
    print('不合法')

# 方法2 利用正则
result = re.fullmatch(r'1[3-9]\d{9}', tel)
if result:
    print('合法')
else:
    print('不合法')
例2:提取字符串中所有的数字子串,并且求和
print('----------------------------------------')
str1 = '睡觉89jss=3.45-换手23=抗生素820=8'
result = re.findall(r'\d+\.?\d*', str1)
print(sum([float(x) for x in result]))

02 正则语法

1.re模块 - 提供了python中所有与正则相关的函数

from re import fullmatch, findall, search

fullmatch(正则表达式, 字符串) - 判断整个字符串是否满足正则表达式所描述的规则
findall(正则表达式, 字符串) - 提取字符串中所有满足正则表达式的子串
search(正则表达式, 字符串) - 匹配字符串中第一个满足正则表达式的子串
Attention:Python中表示一个正则表达式一般使用r字符串

2.正则符号

============== 第一类 匹配类符号 ==============

2.1 普通符号 - 在正则表达式中表符号本身的符号
import requests

print('第一类 匹配类符号----------------------------------------')
result = fullmatch(r'abc', 'abc')
print(result)   # 匹配对象:<re.Match object; span=(0, 3), match='abc'>

2.2 . - 匹配任意一个字符

result = fullmatch(r'.bc', '好bc')
print(result)

2.3 /d - 匹配任意一个数字字符

result = fullmatch(r'\d\dabc', '67abc')
print(result)
2.4 /s - 匹配任意一个空白字符

空白字符:空格(’ ‘)、换行(’\n’)、水平制表符(‘\t’)

result = fullmatch(r'123\sabc', '123 abc')
print(result)
result = fullmatch(r'\d\d\s\d', '13\n5')
print(result)
2.5 \w - 匹配任意一个字母、数字、下划线或者中文
result = fullmatch(r'abc\w123', 'abc和123')
print(result)
2.6 \D、\S、\W - 分别与\d、\s、\w的功能相反
result = fullmatch(r'abc\D123', 'abc6123')
print(result)   # 不匹配,返None
2.7 [字符集] - 匹配在字符集中的任意一个字符

[abc] - 匹配a或者b或者c
[abc\d] - 匹配a或者b或者c或者任意数字
[1-5] - 匹配1-5中任意一个字符
[a-z] - 匹配任意一个小写字母
[A-Z] - 匹配任意一个大写字母
[a-zA-Z] - 匹配任意一个字母
[a-zA-Z\d] - 匹配任意一个字母或数字
[a-z=%] - 匹配任意一个小写字母 + ‘=’ + ‘%’
[\u4e00-\u9fa5] - 匹配任意一个中文字

result = fullmatch(r'abc[M9你\\d]123', rf'abc9123')
print(result)
2.8 [^字符集] - 匹配不在字符集中的任意一个字符
result = fullmatch(r'abc[^MN]123', 'abc.123')
print(result)

============== 第二类 匹配次数符号 ==============
必须先写匹配类符号再跟匹配次数

2.9 * - 任意次数(0次或1次或多次)

a* - a出现任意多次
\d* - 任意多个任意数字
[abc]* - 任意多个abc

print('第二类 匹配次数符号----------------------------------------')
result = fullmatch(r'1a*2', '1aaaaaaaaaaaa2')
print(result)

result = fullmatch(r'M[3-9]*N', 'M569865N')
print(result)
2.10 + - 一次或多次(至少1次)
result = fullmatch(r'Aa+C', 'AaaC')
print(result)
2.11 ? - 0次或1次
result = fullmatch(r'1a?2', '1aa2')
print(result)   # 不匹配,返None
2.12 匹配任意次数的写法

{N} - N次
{M,N} - M到N次
{M,} - 至少M次
{,N} - 最多N次

result = fullmatch(r'1a{3,6}2', '1aaa2')
print(result)
练习1:写一个写一个正则表达式,可以匹配任意一个除了0的整数。

233、+234、-7283

print('练习1----------------------------------------')
result = fullmatch(r'[+-]?[1-9]\\d*', '3330')
print(result)
2.13 ★贪婪和非贪婪模式

在匹配次数不确定的时候,如果有多种次数都可以匹配成功,贪婪取最多的次数,非贪婪取最少的>次数。(默认是贪婪模式)
贪婪模式:+、?、、{M,N}、{M,}、{,N}
非贪婪模式:+?、??、
?、{M,N}?、{M,}?、{,N}?

# 贪婪模式
result = search(r'a.+b', '哈哈哈哈ahkmb是石双德bxybs5151f5')
print(result)   # <re.Match object; span=(4, 17), match='ahkmb是石双德bxyb'>
# 非贪婪模式
result = search(r'a.+?b', '哈哈哈哈ahkmb是石双德bxybs5151f5')
print(result)   # <re.Match object; span=(4, 9), match='ahkmb'>
练习2:使用正则提取top250中每个电影的详情页地址
print('练习2----------------------------------------')
# import requests
# from re import findall
# header = {
#     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.95 Safari/537.36'
# }
# response = requests.get('https://movie.douban.com/top250?start=0&filter=', headers=header)
# result = findall('<a href="(https://movie.douban.com/subject/\d*/)">', response.text)
# print(result)

============== 第三类 ★分组和分支 ==============

2.14 分组 - ()

正则表达式中可以用()将部分内容括起来表示一个整体。括号括起来的部分就是一个分组。
a.整体操作的时候需要分组
b.重复匹配:正则中可以通过\M来重复它前面第M个分组匹配的结果
c.捕获:提取分组匹配到的结果(自动捕获(findall)、手动捕获(其余正则函数))

例1:‘23M’、‘89K10L’、‘09H23P90Q33W’、 …
result = fullmatch(r'(\d\d[A-Z])+', '23M06N58M84V')
print(result)
例2:‘23H23’、‘90K90’、‘78N78’、‘10U10’
result = fullmatch(r'(\d\d)[A-Z]\1', '23M23')
print(result)
result = fullmatch(r'(\d{3})([a-z]{2})=\2\1{2}\2', '231nm=nm231231nm')
print(result)

★自动捕获(findall)函数在正则表达式中有分组的时候,会自动提取正则匹配结果中分组匹配到的内容

message = '极少数234,ckokqwopd5856.959==w积分12ndfk2=e5fv51-511'
result = findall(r'[\u4e00-\u9fa5](\d+)', message)
print(result)

手动捕获(其余正则函数如:search)
匹配对象.group(N) - 获取匹配结果中指定分组匹配到的内容

massage = '我是小明,今年23岁,身高180cm,体重70kg'
result = search(r'身高(\d+)cm,体重(\d+)kg', massage)
print(result)   # 匹配对象:<re.Match object; span=(11, 25), match='身高180cm,体重70kg'>
print(result.group())   # 身高180cm,体重70kg
print(```

#### 2.15 分支  -  |
>正则1|正则2|正则3|...  -  先用正则1进行匹配,若正则1不成功则用正则2进行匹配...若都匹配不成>功则返回None
```python
result = fullmatch(r'\d{3}|[a-z]{2}', 'mn')
print(result)

'abc34’或’abcKJ

result = fullmatch(r'abc(\d{2}|[A-Z]{2})', 'abcKJ')
print(result)

============== 第四类 ★转义符号 ==============

2.16 转义符号:在本身具有特殊功能或特殊意义的符号前加 \ ,让特殊符号变普通字符
print('第四类 ★转义符号----------------------------------------')
# 匹整数部分和小数部分都是两位数的小数
result = fullmatch(r'\d\d\.\d\d', '45.36')
print(result)
result = fullmatch(r'\d\+\d', '4+3')
print(result)
# '(amd)'
result = fullmatch(r'\([a-z]{3}\)', '(amd)')
print(result)   # <re.Match object; span=(0, 5), match='(amd)'>

Attention:单独存在有特殊意义的符号,在[]中它的功能会自动消失

03 re模块补充

from re import fullmatch, findall, search, match, finditer, split, sub, subn, escape

1)fullmatch(正则表达式, 字符串) - 用整个字符串和正则,匹配成功返回匹配对象,匹配失败返回>None。(如匹配手机号、邮箱、IP地址等)
2)findall(正则表达式, 字符串) - 获取字符串中所有满足正则的子串,默认返回一个列表,列表中>的元素是所有匹配到的子串。(存在自动捕获现象)
3)search(正则表达式, 字符串) - 匹配字符串中第一个满足正则表达式的子串。若匹配失败则返>None
4)split(正则表达式, 字符串, [N]) - 将字符串中所有满足正则的子串作为切割点进行切割,[N]是>用前N个来进行切割
5)sub(正则表达式, 字符串1, 字符串2) - 将字符串2中所有满足正则的子串都替换成字符串1
6)sub(正则表达式, 字符串1, 字符串2, N) - 将字符串2中前N个满足正则表达式的子串替换成字符>串1
7)finditer(正则表达式, 字符串) - 获取字符串中所有满足正则的子串,返回一个迭代器,迭代器>中的元素是匹配对象
8)match(正则表达式, 字符串) - 匹配字符串开头

# 用字符串的切割函数来切割
str1 = '技术7晋级赛7sks7就开始看'
print(str1.split('7'))

# 用正则的切割模块来切割
str2 = '技术22晋级赛7sks5就开始8看'
print(split(r'\d+', str2, 2))   # ['技术', '晋级赛', 'sks5就开始8看']

str3 = '技术22晋级赛7sks5就开始8看'
print(sub(r'\d+', '+', str3))   # 技术+晋级赛+sks+就开始+看

message = '妈的,sb,SB,都打起来了你还在打野!草!fuck'
print(sub(r'(?i)妈的|sb|草|操|艹|f\s*u\s*c\s*k', '*', message))

str4 = '技术22晋级赛7sks5就开始8看'
result = finditer(r'\d+', str4)
print(list(result))
# print(list(result)[1].group())

print(fullmatch(r'\d{3}', '234'))
print(match(r'\d{3}', '234卡咖啡'))

补充1:匹配时忽略大小写

print(fullmatch(r'abc', 'abc'))   # 一般情况
print(fullmatch(r'(?i)abc', 'AbC'))   # 忽略大小写

补充2:

单行匹配:(?s)

print(fullmatch(r'(?s)abc.123', 'abc\n123'))   # <re.Match object; span=(0, 7), match='abc\n123'>

多行匹配(默认):. - 不能和换行符进行匹配

print(fullmatch(r'abc.123', 'abc\n123'))   # None

msg = """
'name:"jshf2-
2ss技术"'
"""
result =findall(r'(?s)name:"(.+)"', msg)
print(result)

04 正则表达式作业

一、不定项选择题
  1. 能够完全匹配字符串"(010)-62661617"和字符串"01062661617"的正则表达式包括( A B D)

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

  2. 能够完全匹配字符串"back"和"back-end"的正则表达式包括( A B C )
    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*'

  3. 能够完全匹配字符串"go go"和"kitty kitty",但不能完全匹配“go kitty”的正则表达式包括(D)
    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'

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

二、编程题

1.用户名匹配

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

					2.不能以数字开头 

					3.⻓度在 6 到 16 位范围内
username = 'dwdw_wdf'
result = fullmatch(r'\D[\dA-Za-z_]{5,15}', username)
print(result)
  1. 密码匹配

     		要求:	1.不能包含!@#¥%^&*这些特殊符号
     
     					2.必须以字母开头 
     
     					3.⻓度在 6 到 12 位范围内
    
password = 'dwdw_wdf'
result = fullmatch(r'[A-Za-z][^!@#¥%^&*]{5,11}', password)
print(result)
  1. ipv4 格式的 ip 地址匹配
    提示: IP地址的范围是 0.0.0.0 - 255.255.255.255
ipv4 = '155.255.8.0'
result = fullmatch(r'([0-9]|[1-5][1-5]|[1-2]?[1-5][1-5])\.([0-9]|[1-5][1-5]|[1-2]?[1-5][1-5])\.([0-9]|[1-5][1-5]|[1-2]?[1-5][1-5])\.([0-9]|[1-5][1-5]|[1-2]?[1-5][1-5])', ipv4)
print(result)
  1. 提取用户输入数据中的数值 (数值包括正负数 还包括整数和小数在内) 并求和
例如:“-3.14good87nice19bye” =====> -3.14 + 87 + 19 = 102.86
str4 = '-3.14good87nice19bye'
result = eval('+'.join(findall(r'[+-]?\d+\.?\d+', str4)))
print(result)
  1. 验证输入的内容只能是汉字
str5 = '哈哈哈哈'
result = fullmatch(r'[\u4e00-\u9fa5]*', str5)
print(result)
  1. 匹配整数或者小数(包括正数和负数)
str6 = '-12.3'
result = fullmatch(r'[+-]?\d+\.?\d+', str6)
print(result)
  1. 验证输入用户名和QQ号是否有效并给出对应的提示信息

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

username = input('用户名:')
qq = input('QQ:')
result1 = fullmatch(r'[A-Za-z\d_]{6,20}', username)
result2 = fullmatch(r'[1-9]\d{4,11}', qq)
print(result1)
print(result2)
  1. 拆分长字符串:将一首诗的中的每一句话分别取出来

       poem = '窗前明月光,疑是地上霜。举头望明月,低头思故乡。'
    
poem = '窗前明月光,疑是地上霜。举头望明月,低头思故乡。'
result = findall(r'[\u4e00-\u9fa5]+[,。]?', poem)
print(result)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值