作业
作业
利用正则表达式完成下面的操作:
一、不定项选择题
能够完全匹配字符串"(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"
能够完全匹配字符串“back”和“back-end”的正则表达式包括( A ,B,C,D )
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*”
能够完全匹配字符串“go go”和“kitty kitty”,但不能完全匹配“go kitty”的正则表达式包括(A, 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”
能够在字符串中匹配“aab”,而不能匹配“aaab”和“aaaab”的正则表达式包括(B,C )
A. r“a*?b”
B. r“a{,2}b”
C. r“aa??b”
D. r“aaa??b”
二、编程题
import re
1
1.用户名匹配
要求: 1.用户名只能包含数字 字母 下划线
2.不能以数字开头
3.⻓度在 6 到 16 位范围内
1
2
3
4
5
密码匹配
要求: 1.不能包含!@#¥%^&*这些特殊符号
2.必须以字母开头
3.⻓度在 6 到 12 位范围内
1
2
3
4
5
题1,题2
class user:
def init(self, name, pwd):
self.name = name
self.pwd = pwd
def check_name(self):
re_name = r'[A-Za-z_]\w{5,15}'
result = fullmatch(re_name, self.name)
if result:
return True
return False
def check_pwd(self):
re_pwd = r'[A-Za-z][^!@#¥%^&*]{5,11}'
result = fullmatch(re_pwd, self.pwd)
if result:
return True
return False
user1 = user(‘llfaweafeo’, ‘aeffaew2’)
if user1.check_name():
print(f’{user1.name}通过’)
else:
print(f’{user1.name}不通过’)
if user1.check_pwd():
print(f’{user1.pwd}通过’)
else:
print(f’{user1.pwd}不通过’)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
ipv4 格式的 ip 地址匹配
提示: IP地址的范围是 0.0.0.0 - 255.255.255.255
提示:001.001.001.001 计算机也可以识别
def is_ipv4(in_str):
def is_ipv4(in_str):
# 25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9]
reg = r’((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9]).){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])’
result = fullmatch(reg, in_str)
if result:
return True
return False
ipv4 = ‘133.13.12.56’
if is_ipv4(ipv4):
print(f’{ipv4}是ipv4’)
else:
print(f’{ipv4}不是ipv4’)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
提取用户输入数据中的数值 (数值包括正负数 还包括整数和小数在内) 并求和
例如:“-3.14good87nice19bye” =====> -3.14 + 87 + 19 = 102.86
1
def get_sum(input_str):
reg = r’(-?([1-9]\d*|0)[.]?\d*)’
list1 = findall(reg, input_str)
return sum([eval(x[0]) for x in list1])
result = get_sum("-3.14good87nice19bye")
print(result)
1
2
3
4
5
6
7
验证输入内容只能是汉字
def is_chinese(in_str: str) -> bool:
reg = r’[\u4e00-\u9fa5]*’
result = fullmatch(reg, in_str)
if result:
return True
return False
chinese_str = input(‘请输入汉字字符串:’)
if is_chinese(chinese_str):
print(f’{chinese_str} 全是汉字’)
else:
print(f’{chinese_str} 不全是汉字’)
1
2
3
4
5
6
7
8
9
10
11
12
13
匹配整数或者小数(包括正数和负数)
def is_num(in_str: str) -> bool:
reg = r’[-+]?([1-9]\d*|0)(.\d*)?’
result = fullmatch(reg, in_str)
if result:
return True
return False
num = input(‘请输入一个数字:’)
if is_num(num):
print(f’{num}是数字’)
else:
print(f’{num}不是数字’)
1
2
3
4
5
6
7
8
9
10
11
12
13
验证输入用户名和QQ号是否有效并给出对应的提示信息
要求:
用户名必须由字母、数字或下划线构成且长度在6~20个字符之间
QQ号是5~12的数字且首位不能为0
class qquser:
def init(self, nickname, qq):
self.nickname = nickname
self.qq = qq
def validity(self):
reg1 = r'\w{6,20}'
reg2 = r'[1-9]\d{4,11}'
res1 = fullmatch(reg1, self.nickname)
res2 = fullmatch(reg2, self.qq)
if res1:
if res2:
return True, ''
else:
return False, 'qq格式有误!'
return False, '用户名格式有误!'
def __str__(self):
return str({'name': self.nickname, 'qq': self.qq})
qquser1 = qquser(‘12le2@ifaei’, ‘12242463242’)
flag, msg = qquser1.validity()
if flag:
print(f’{qquser1}合法’)
else:
print(f’{qquser1}不合法,{msg}’)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
拆分长字符串:将一首诗的中的每一句话分别取出来
poem = ‘窗前明月光,疑是地上霜。举头望明月,低头思故乡。’
1
def poem_word(poem: str):
reg = r’\b[,。;、:‘” ]’
if search(r’[,。;、:‘” ]$’, poem):
list1 = split(reg, poem)
return list1[:-1]
else:
list1 = split(reg, poem)
return list1[:-1]
poem = ‘窗前明月光,疑是地上霜。举头望明月,低头思故乡。’
list1 = poem_word(poem)
print(list1)
————————————————
版权声明:本文为CSDN博主「??fengyu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_46137199/article/details/117000702
总结
检测类符号
e_str = r'abc \b123'
print(fullmatch(re_str, 'abc 123'))
re_str = r'\b\d\d\b'
result = findall(re_str, 'shj23结合实际 45 计时开始67,数据,89.计算机90l 78')
print(result)
-
\B - 检测是否不是单词边界
re_str = r'\B\d\d\B' result = findall(re_str, '99shj23结合实际 45 计时开始67,数据,89.计算机90l 78') print(result)
-
^ - 检测是否是字符串开头
re_str = r'^\d\d' result = findall(re_str, '99shj23结合实际 45 计时开始67,数据,89.计算机90l 78') print(result)
-
$ - 检测是否是字符串结尾
re_str = r'\d\d$' result = findall(re_str, '99shj23结合实际 45 计时开始67,数据,89.计算机90l 78') print(result) re_str = r'^\d\d\d$'
匹配次数
from re import fullmatch, match, search, findall
"""
三个a: 'aaa' == 'a{3}'
三个数字: '\d\d\d' == '\d{3}'
2到5个大写字母: '[A-Z]{2,5}'
"""
-
* - 0次或者多次(任意次数)
""" a* - a出现0次或多次 \d* - \d出现0次或多次,每次的一个\d可以是任意一个数字 [abc]* - [abc]出现0次或多次,每次的[abc]都可以在a、b、c中任意选一个 """ re_str = r'a\d*b' print(fullmatch(re_str, 'ab')) print(fullmatch(re_str, 'a4b')) print(fullmatch(re_str, 'a434510b'))
-
+ - 1次或多次(至少一次)
re_str = r'a\d+b' print(fullmatch(re_str, 'ab')) # None print(fullmatch(re_str, 'a4b')) print(fullmatch(re_str, 'a434510b'))
-
? - 0次或1次
re_str = r'[-+]?[1-9]\d' print(fullmatch(re_str, '+16')) print(fullmatch(re_str, '-16')) print(fullmatch(re_str, '16'))
-
{}
""" {N} - 匹配N次 {M,N} - 匹配M到N次,M和N都可以取到 {M,} - 匹配至少M次 {,N} - 匹配最多N次 """ re_str = r'1a{2,5}2' print(fullmatch(re_str, '1aaaaa2')) re_str = r'1a{3}2' print(fullmatch(re_str, '1aaa2'))
-
贪婪和非贪婪
""" 在匹配次数不确定的时候才有贪婪和非贪婪两种模式。 贪婪:在能匹配成功的前提下取匹配次数最多的次数。(默认) 非贪婪:在能匹配成功的前提下去匹配次数最少的次数。(在匹配次数后加?) """ re_str = r'a.+?b' print(fullmatch(re_str, 'a神兽金刚234b密码门b')) print(match(re_str, 'asjsbhhhb123b脚手架水电费')) # 3次 7次 11次 import requests headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36' } response = requests.get('https://movie.douban.com/top250?start=0', headers=headers) content = response.text result = findall(r'alt="(.+?)"', content) print(result) # a??
分组和分支
from re import fullmatch
# 1. 分组 - ()
"""
用法1: 将正则表达式中的一部分作为一个整体,进行整体相关操作,比如控制次数
用法2: 重复-使用\M来重复前面第M个分组中的内容
用法3: 捕获
"""
# 'amn23abm45mnh78'
# re_str = r'[a-z]{3}\d{2}[a-z]{3}\d{2}[a-z]{3}\d{2}'
re_str = r'([a-z]{3}\d{2}){3}'
print(fullmatch(re_str, 'amn23abm45mnh78'))
# '22a34a56a43'
re_str = '(\d{2}a){3}\d{2}'
print(fullmatch(re_str, '22a34a56a43'))
# '34abc34'、 '78abc78'、'01abc01'
re_str = r'(\d\d)abc\1'
print(fullmatch(re_str, '12abc12'))
print(fullmatch(re_str, '12abc21')) # None
re_str = r'(\d{2})=([\u4e00-\u9fa5])=\2=\1'
print(fullmatch(re_str, '12=好=好=12'))
re_str = r'(\d{2})=\1=([\u4e00-\u9fa5])=\2'
print(fullmatch(re_str, '34=34=是=是'))
# 2.分支 - |
"""
正则表达式1|正则表达式2 - 先让正则1和字符进行匹配,如果成功就成功,如果失败就和正则2进行匹配,
如果正则2成功结果匹配成功,否则匹配失败。(两个正则中只有一个可以匹配成功结果就成功否则失败)
"""
# '23abc'、'MKHabc'
re_str = r'\d{2}abc|[A-Z]{3}abc'
print(fullmatch(re_str, '23abc'))
re_str = r'(\d{2}|[A-Z]{3})abc'
print(fullmatch(re_str, '23abc'))
# 3.转义符号
# 在本身具备特殊功能或者特殊意义的符号加\,让其功能或者意义消失,表示一个普通符号
# '23.67'、'90.01'
re_str = r'[1-9]\d\.\d{2}'
print(fullmatch(re_str, '19.37'))
# '2+8'
re_str = r'\d\+\d'
print(fullmatch(re_str, '6+7'))
# 注意:独立具备特殊功能的符号在[]中功能会自动消失,例如: +、*、?、.、(、)等
# 本身在[]中有特殊意义的就要特别注意: ^、-、[、]
re_str = r'\d[\^\].-]\d'
print(fullmatch(re_str, '6]7'))
re模块
import re
from re import *
-
compile(正则表达式) - 创建一个正则表达式对象
re_obj = compile(r'\d{3}') result = re_obj.fullmatch('123') print(result) fullmatch(r'\d{3}', '123') print(result)++
-
匹配类方法
“”"
- fullmatch
fullmatch(正则表达式, 字符串)
正则表达式对象.fullmatch(字符串) - 判断整个字符串是符合正则表达式描述的规则,如果不符合返回None,符合返回匹配对象。
2)match
match(正则表达式, 字符串)
正则表达式对象.match(字符串) - 判断字符开头是否符合正则表达式描述的规则,如果不符合返回None,符合返回匹配对象。
“”"result = match(r'((\d{3})-)([a-z]{2,5})', '829-dhm技术交底㐇shs---23') print(result)
1)获取匹配结果
匹配对象.group() / 匹配对象.group(0) - 获取整个正则表达式匹配到的结果
匹配对象.group(N) - 获取正则表达式中第N个分组匹配到的结果
print(result.group(0)) # '829-dhm' print(result.group(1)) # '829-' print(result.group(2)) # '829'
2)获取匹配结果在原字符中的位置
匹配对象.span()
匹配对象.span(N)
print(result.span()) # [0, 7) print(result.span(3)) # [4, 7)
3)获取原字符串
匹配对象.string
print(result.string) # '829-dhm技术交底㐇shs---23'
- fullmatch
-
查找类方法
“”"
search(正则表达式, 字符串)
正则表达式对象.search(字符串) - 获取字符串中第一个满足正则表达式的子串,如果没有返回None,否则返回匹配对象
“”"result = search(r'\d{3}', 'shhs2728309990数据是992sjsj--sjss数据是099') print(result) # <re.Match object; span=(4, 7), match='272'>
“”"
findall(正则表达式, 字符串)
正则表达式对象.findall(字符串) - 获取字符串中所有满足正则表达式的子串, 以列表的形式返回,列表中的元素是字符串
“”"str1 = 'shj24萨克斯38904=-37ml899计算机上3,90m7788' result = findall(r'\d+', str1) # ['24', '38904', '37', '899', '3', '90', '7788'] print(result)
result = findall(r'[\u4e00-\u9fa5]\d+', str1) print(result) # ['斯38904', '上3']
如果正则中有分组,findall只提取匹配结果中分组匹配到的内容
result = findall(r'[\u4e00-\u9fa5](\d+)', str1) print(result) # ['38904', '3'] result = findall(r'\d+-[a-z]+', 'hshs899-mn生死狙击2-mkl==-892-ma=计算机') print(result) # ['899-mn', '2-mkl', '892-ma'] result = findall(r'\d+-([a-z]+)', 'hshs899-mn生死狙击2-mkl==-892-ma=计算机') print(result) # ['mn', 'mkl', 'ma'] result = findall(r'((\d+)-([a-z]+))', 'hshs899-mn生死狙击2-mkl==-892-ma=计算机') print(result) # [('899', 'mn'), ('2', 'mkl'), ('892', 'ma')]
“”"
finditer(正则表达式, 字符串)
正则表达式对象.finditer(字符串) - 获取字符串中所有满足正则表达式的子串,返回值是迭代器,迭代器中的元素是匹配对象
“”"str1 = 'shj24萨克斯38904=-37ml899计算机上3,90m7788' result = finditer(r'\d+', str1) print(list(result)) result = finditer(r'(\d+)-([a-z]+)', 'hshs899-mn生死狙击2-mkl==-892-ma=计算机') print('整个正则匹配结果:', [x.group() for x in result]) result = finditer(r'(\d+)-([a-z]+)', 'hshs899-mn生死狙击2-mkl==-892-ma=计算机') print('分组1的匹配结果:', [x.group(1) for x in result])
-
切割
“”"
split(正则表达式, 字符串)
正则表达式对象.split(字符串) - 将字符串中所有满足正则表达式的子串作为切割点对字符串进行切割split(正则表达式, 字符串, 最大切割数)
“”"str1 = '节省时间27计算机上9sjjsn6计算机0292jsjsn就几节课2-==解决' result = split(r'\d+', str1) print(result) # ['节省时间', '计算机上', 'sjjsn', '计算机', 'jsjsn就几节课', '-==解决'] str2 = '失敬失敬,啥的看法和。适得府君书就,随叫随到加分号。是计算机上' result = split(r'[,。]', str2) print(result) # ['失敬失敬', '啥的看法和', '适得府君书就', '随叫随到加分号', '是计算机上'] result = split(r'[,。]', str2, 3) print(result)+
-
替换
“”"
sub(正则表达式, 字符串1, 字符串2)
正则表达式对象.sub(字符串1, 字符串2) - 将字符串2中所有满足正则表达式的子串都替换成字符串1
“”"result = sub(r'\d+', '+', '试试7数据09jsjs8989sj计算机上-=') print(result) # 试试+数据+jsjs+sj计算机上-= result = sub(r'\d', '+', '试试7数据09jsjs8989sj计算机上-=') print(result) # 试试+数据++jsjs++++sj计算机上-= result = sub(r'傻[bB逼]|f\s*u\s*c\s*k', '*', 'f u c k!') print(result) result = sub(r'\d', '+', '试试7数据09jsjs8989sj计算机上-=', 3) print(result) # 试试+数据++jsjs8989sj计算机上-=
匹配参数
from re import fullmatch, S, I
匹配参数:1.单行匹配、2.忽略大小写
-
1.单行匹配和多行匹配
“”"
默认是多行匹配。
多行匹配的时候.不能和\n(换行)匹配; 单行匹配的时候.可以和\n匹配
“”"多行匹配
print(fullmatch(r'a.b', 'a\nb')) # None
单行匹配
S是从re模块中导入的
print(fullmatch(r'a.b', 'a\nb', flags=S)) # <re.Match object; span=(0, 3), match='a\nb'> print(fullmatch(r'(?s)a.b', 'a\nb')) # <re.Match object; span=(0, 3), match='a\nb'>
-
忽略大小写
“”"
默认不忽略大小写。
忽略大小写的时候,大写字母可以喝对应的小写字母匹配,小写字母也可以和对应的大写字母匹配
“”"print(fullmatch(r'[a-z]{3}123', 'hSm123')) # None
忽略大小写
print(fullmatch(r'[a-z]{3}123', 'hSM123', flags=I)) # <re.Match object; span=(0, 6), match='hSM123'> print(fullmatch(r'(?i)[a-z]{3}123', 'hSM123')) # <re.Match object; span=(0, 6), match='hSM123'>
单行匹配和忽略大小写同时进行
print(fullmatch(r'abc.123', 'ABC\n123', flags=I|S)) # <re.Match object; span=(0, 7), match='ABC\n123'> print(fullmatch(r'(?si)abc.123', 'ABC\n123')) # <re.Match object; span=(0, 7), match='ABC\n123'>
编程思想
面向过程编程(穷人思想) - 逻辑+算法
函数式编程(小资思想) - 函数
面向对象编程(富豪思想) - 类和对象