day16
总结
1.正则表达式
-
检测字符
-
\b - 检测是否是单词边界(检测用,不做匹配用)
""" 单词边界: 凡是可以两个单词分开的符号都是单词边界, 比如:空白字符,标点符号对应的字符,字符串开头和结束 注意:检测类符号是在匹配成功的情况霞看检测类符号所在的位置是否符合要求。 """ result = fullmatch(r'how \bare', 'how are') print(result) # <re.Match object; span=(0, 7), match='how are'> result = findall(r'\b\d\d\b', '13 44 3524') print(result) # ['13', '44']
-
\B - 检测是否不是单词边界
result = findall(r'\B\d\d\B', '13 44 3524') print(result) # ['52']
-
^ - 检测是否是字符串开头
result = findall(r'^ab', 'ab43245') print(result) # ['ab']
-
$ - 检测是否是单词结尾
result = findall(r'123$', 'abc123') print(result) # ['123']
-
-
匹配次数
-
* - 0次或者多次
result = findall(r"[0-9a-zA-Z]*", '14fa4f2') print(result) # ['14fa4f2', ''] # 非贪婪 result = findall(r"[0-9a-zA-Z]*?[0-9]", '14fa4323f2') print(result) # ['1', '4', 'fa4', '3', '2', '3', 'f2']
-
+ - 1次或者多次
-
? - 0次或者1次
-
{N, M} - 匹配[N, M]次
# {N} - 匹配N次 # {N,} - 至少匹配N次 # {,M} - 最多匹配M次 re_str = r'\d{2,}' result = fullmatch(re_str, '14124') print(result) # <re.Match object; span=(0, 5), match='14124'>
-
贪婪和非贪婪
""" 在匹配次数不确定的时候才有贪婪和非贪婪两种模式。 贪婪:在能匹配成功的前提下取匹配次数最多的次数。(默认) 非贪婪:在能匹配成功的前提下去匹配次数最少的次数。(在匹配次数后加?) """ re_str = r'a.+b' re_str2 = r'a.+?b' print(fullmatch(re_str, 'a身上发欸b发i额bfae ifa2479bfaeb')) # <re.Match object; span=(0, 26), match='a身上发欸b发i额bfae ifa2479bfaeb'> print(match(re_str, 'a身上发欸b发i额bfae ifa2479bfaeb')) # <re.Match object; span=(0, 26), match='a身上发欸b发i额bfae ifa2479bfaeb'> print(match(re_str2, 'a身上发欸b发i额bfae ifa2479bfaeb')) # <re.Match object; span=(0, 6), match='a身上发欸b'>
-
-
分组和分支
-
分组 - ()
""" 用法1: 将正则表达式中的一部分作为一个整体,进行整体相关操作,比如控制次数 用法2: 重复-使用\M来重复前面第M分分组中的内容 """ # 用法1: 将正则表达式中的一部分作为一个整体,进行整体相关操作,比如控制次数 # ‘aaf123fae345fae453' re_str = r'([a-z]{3}\d{3}){3,}' print(match(re_str, 'aaf123fae345fae453')) re_str = r'(https?:\\\\)?(\d+\.){3}\d+' print(search(re_str, r'https:\\114.114.114.114').groups()) # 用法2: 重复-使用\M来重复前面第M分分组中的内容 # '34abc34' '78abc78' '1234fae1234' re_str = r'(\d\d)abc\1' print(match(re_str, '34abc34')) # <re.Match object; span=(0, 7), match='34abc34'> re_str = r'(\d{2})=([\u4e00-\u9fa5])=\2=\1' print(fullmatch(re_str, '12=号=号=12').groups()) # ('12', '号') print(findall(re_str, '12=号=号=12 13=号=号=13')) # [('12', '号')]
-
分支 - |
""" 正则表达式1|正则表达式2 - 先让正则1和字符串进行匹配,如果成功就成功,如果失败就和正则2进行匹配 如果正则2成功结果匹配成功,否则匹配失败。(两个正则中只有一个可以匹配成功) """ re_str = r'\d{2}abc|[A-Z]{3}abc' print(fullmatch(re_str, '12abc')) # <re.Match object; span=(0, 5), match='12abc'> re_str = r'(\d{2}|[A-Z]{3})abc' print(fullmatch(re_str, '12abc')) # <re.Match object; span=(0, 5), match='12abc'>
-
-
转义符号
# 在本身具备特殊功能或者特殊意义的符号加\,让其功能或者意义消失,表示一个不同符号 re_str = r'[1-9]\d\.\d{2}' print(fullmatch(re_str, '50.12')) # <re.Match object; span=(0, 5), match='50.12'> # 注意:独立具备特殊功能的符号在[]中功能会自动消失,例如:+、*、?、.、(、)等 # 本身在[]中有特殊意义的就要特别注意: ^,-,[,]
-
re模块
-
compile() - 创建一个正则表达式对象
# re.compile(正则表达式) re_obj = re.compile(r'\d{3}') print(re_obj) result = re_obj.fullmatch('132') print(result) # <re.Match object; span=(0, 3), match='132'>
-
fullmatch - 判断某个字符串是符合正则表达式描述的规则,如果不符合放回None,符号返回匹配对象
result = fullmatch(re_obj, '243') print(result) # <re.Match object; span=(0, 3), match='243'>
-
match - 判断字符串开头是否符合正则表达式描述规则,如果不符合返回None,符合返回匹配对象
re_obj = re.compile(r'\d{3}([\u4e00-\u9fa5]{,3})') result = re_obj.match('876解法二按附件欸-----------23') print(result, type(result)) # <re.Match object; span=(0, 3), match='876'> <class 're.Match'> # 1) 匹配对象.group() - 获取匹配结果 # 匹配对象.group(N) - 获取正则表达式中第N个分组匹配到的结果 # 匹配对象.groups() - 获取正则表达式中的[1,N]个分组匹配到的结果 print(result.group()) # 876解法二 print(result.group(1)) # 解法二 print(result.groups()) # ('解法二',) # 2) 匹配对象.span() - 获取匹配结果在原字符串中的位置 print(result.span()) # (0, 6) [0, 6) print(result.span(1)) # (3, 6) [3, 5) # 3) 获取原字符串 print(result.string) # 876解法二按附件欸-----------23
-
search - 获取正则表达式中第一个满足正则表达式的字串,如果没有返回None,有返回匹配对象
re_obj = re.compile(r'\d{3}') result = re_obj.search('faewf124fjau2affawe') print(result) # <re.Match object; span=(5, 8), match='124'>
-
findall - 获取字符串中所有满足正则表达式的子串,以列表的形式返回,列表中的元素是字符串
result = re_obj.findall('123424341324baf24i42') print(result) # ['123', '424', '341', '324'] re_obj2 = re.compile(r'(\d{3}([a-z])([a-z]))') print(re_obj2.findall('123424341324baf24142afew243afefa32413b')) # [('324ba', 'b', 'a'), ('142af', 'a', 'f'), ('243af', 'a', 'f')]
-
finditer - 获取字符串中所有满足正则表达式的字串,以迭代器返回,迭代器中的元素是匹配对象
iter1 = re_obj2.finditer('123424341324baf24142afew243afefa32413b') for obj in iter1: print(obj.group(), type(obj)) # <class 're.Match'> iter1 = re_obj2.finditer('123424341324baf24142afew243afefa32413b') print([obj.group() for obj in iter1]) # ['324ba', '142af', '243af']
-
split - 将字符串中所有满足正则表达式的子串作为切割点对字符串进行切割
re_obj = re.compile(r'[,。]') list1 = re_obj.split('解法二,发欸发ihi啊鹅。乏味,发纹阿尔法二啊覅i我i。', 2) print(list1) # ['解法二', '发欸发ihi啊鹅', '乏味,发纹阿尔法二啊覅i我i。']
-
sub - 将字符串中所有符合正则表达式的子串都替换成新字符串
re_obj = re.compile(r'\d+') result = re_obj.sub('+', 'faeeg1324jfawe124fai324u24fa2343t24') print(result) # faeeg+jfawe+fai+u+fa+t+
-
-
匹配参数
-
单行匹配和多行匹配
""" 默认多行匹配。 多行匹配的时候,不能和\n(换行)匹配 """ re_obj = re.compile(r'a.b') print(re_obj.fullmatch('a\nb')) # None print(fullmatch(r'a.b', 'a\nb', flags=re.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]+', 'AFAWafweFAWEIfaweFAErefIER', flags=re.I)) # <re.Match object; span=(0, 26), match='AFAWafweFAWEIfaweFAErefIER'> print(fullmatch(r'[a-z]+\n[A-Z]*', 'AFAWafweFA\nWEIfaweFAErefIER', flags=re.I|re.S)) # <re.Match object; span=(0, 27), match='AFAWafweFA\nWEIfaweFAErefIER'> print(fullmatch(r'(?is)[a-z]+\n[A-Z]*', 'AFAWafweFA\nWEIfaweFAErefIER')) # <re.Match object; span=(0, 27), match='AFAWafweFA\nWEIfaweFAErefIER'>
-
2. 面向对象
-
# 面向过程编程(穷人思想) - 逻辑+算法 # 函数式编程(小资思想) - 函数 # 面向对象编程(富豪思想) - 类和对象 # 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*"
-
能够完全匹配字符串“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.用户名只能包含数字 字母 下划线
2.不能以数字开头
3.⻓度在 6 到 16 位范围内
-
密码匹配
要求: 1.不能包含!@#¥%^&*这些特殊符号 2.必须以字母开头 3.⻓度在 6 到 12 位范围内
# 题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_][\dA-Za-z_]{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}不通过')
- 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]\d|1\d\d|[1-9]\d|\d
reg = r'((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)'
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')
- 提取用户输入数据中的数值 (数值包括正负数 还包括整数和小数在内) 并求和
例如:“-3.14good87nice19bye” =====> -3.14 + 87 + 19 = 102.86
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)
- 验证输入内容只能是汉字
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} 不全是汉字')
- 匹配整数或者小数(包括正数和负数)
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}不是数字')
-
验证输入用户名和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}')
-
拆分长字符串:将一首诗的中的每一句话分别取出来
poem = '窗前明月光,疑是地上霜。举头望明月,低头思故乡。'
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)