210222课堂整理(异常捕获和正则)
异常捕获
1,异常:
程序运行时报错,即为异常
**后果:**程序会在异常的地方直接结束,不会继续往后执行
2,异常捕获
目的: 程序出现异常时,还可以继续执行后面的代码
**需要捕获的条件:**知道某个地方会出现异常,如代码没问题,由用户的异常操作导致,此时需要异常捕获
语法1: 捕获所有异常
try:
代码1 需要捕获异常的代码
except:
代码2 捕获异常后的补救代码
**执行过程:**先执行代码1,如无异常,不执行代码2,直接执行后面的其他代码;否则,执行代码2
try:
age = int(input('输入年龄:'))
except:
print('年龄输入有误')
age = 0
print(f'年龄是:{age}')
# 练习:打开指定的文本文件,如果文件存在就读文件中的内容,如果不存在就创建这个文件。
try:
with open('./aaa.txt', 'r', encoding='utf-8') as f:
print(f.read())
except:
print('该文件不存在!')
with open('./aaa.txt', 'w', encoding='utf-8') as f:
pass
语法2:捕获指定类型的异常
try:
代码段1
except 异常类型:
代码段2
说明:异常类型:在控制台显示error前面的类型
try:
list1 = [10, 20, 30]
print(list1[3])
print({'a': 10, 'b': 20}['aa'])
except IndexError:
print('出现异常')
except KeyError:
print('出现异常')
语法3 同时捕获多个异常,针对不同异常进行相同处理
try:
代码段1
except (异常类型1,异常类型2)
代码段2
语法4 同时捕获多个异常,针对不同异常进行不同处理
try:
代码段1
except 异常类型1
代码段11
except 异常类型2
代码段22
3,关键字 finally
finally的存在不影响原来异常捕获的执行
finally后面的代码是不管try里面的代码发生什么情况都会执行
try:
print('hello world!')
# print('abc'[100])
print({'a':19}['b'])
except IndexError:
print('出现了异常')
finally:
print('出现其他异常,留存')
正则相关符号及运用
1,正则表达式
让复杂的字符串处理变得更加简单的工具
2,正则语法
fullmatch(正则表达式,字符串)
判断指定的字符串是否满足正则表达式描述的原则,如不满足返回None
Python中正则表达式是写到单引号或双引号里面的
例如’正则表达式‘
3,匹配类符号(一个符号必须匹配一个对应的字符)
1)普通字符
正则表达式中除了特殊符号以外的符号都是普通字符
普通字符在正则中表示这个符号本身
from re import fullmatch
导入正则模块
规则:一个字符串有3个字符,且第一个是a,第二个是b,第三个是c
re_str = ‘abc’
result = fullmatch(re_str, ‘abc’)
print(result)
2) 特殊字符
包含: . \d \D \s \S [] [^]
- . 点 匹配一个任意字符
**规则:**一个字符串有3个字符,第1个是a,最后一个是c,中间是任意字符
re_str = 'a.c'
result = fullmatch(re_str, 'a胡c')
print(result)
# 练习:写一个正则能够匹配一个字符串的开头是1结尾是2,中间2个任意字符
result = fullmatch('1..2', '1ab2')
print(result)
- \d 匹配一个任意数字字符
反斜杠前面加r,避免与转义字符冲突
**规则:**一个字符串有4个字符,第一个是a,最后一个是b,中间是任意两个字符
re_str = r'a\d\db'
result = fullmatch(re_str, 'a49b')
print(result)
- \D 匹配任意一个非数字字符
**规则:**一个字符串有4个字符,第一个字符不是数字,后面是abc
re_str = r'\Dabc'
result = fullmatch(re_str, '=abc')
print(result)
- \s 匹配一个任意空白字符,对应数字
空白字符:空格 \n \t
反斜杠前面加r,避免与转义字符冲突
**规则:**一个字符串开头是2个数字,中间1个空白,后边跟2个数字
re_str = r'\d\d\s\d\d'
result = fullmatch(re_str, '23 89')
print(result)
- \S 匹配任意一个非空白字符
**规则:**一个字符串有5个字符,第1个是数字字符,第2个不是空白字符,后面是abc
re_str = r'\d\Sabc'
result = fullmatch(re_str, '8=abc')
print(result)
- [字符集] 匹配字符集中任意一个字符
注意:一个中括号[]只能匹配一个字符,
括号里面写多少个字符就可以匹配多少个
注意:-减号在2个字符之间表示范围,-前面的字符编码值必须小于后面的编码值
-减号在2个字符以外,表示减号
[abc你] 能匹配’a’或者’b’或者’你’
[abc\d] 能匹配’a’或者’b’或者’任意一个数字’
[1-9] 匹配1到9中任意一个数字字符
[a-z] 匹配任意一个小写字母
[A-Z] 匹配任意一个大写字母
[A-Z\d] 匹配任意一个大写字母或者任意一个数字
[a-zA-Z] 匹配任意一个字母
[\u4e00-\u9fa5] 匹配任意一个中文
re_str = r'1[a=bc0]2'
result = fullmatch(re_str, r'102')
print(result)
re_str = r'1[\dxy胡]2'
result = fullmatch(re_str, '192')
print(result)
re_str = r'a[2345678]b'
re_str = r'a[2-8]b' # [2-8] 2到8中间任意一个数字
result = fullmatch(re_str, r'a3b')
print(result)
# 练习:写一个正则表达式匹配一个字符:123前面是一个数字、字母或者下划线
re_str = r'[\da-zA-Z_]123'
result = fullmatch(re_str, '1123')
print(result)
- [^字符 ] 匹配不在字符集中的任意一个字符
- [^abc ] 匹配一个除了‘a’ ‘b’ 'c’以外的任意字符
- [^a-zA-Z] 匹配任意一个非字母字符
re_str = r'[^abc]123'
result = fullmatch(re_str, 'A123')
print(result)
4,检测类符号:检测字符所在位置是否符合要求
检测类符号不影响匹配,不参与匹配
包含: \b \B ^ $
1) \b 检测是否是单词边界
单词边界包括:空白、标点符号、字符串开头或结尾 (所有可以划分出2个不同单词的符号)
from re import fullmatch, search
# 导入re模块
re_str = r'abc\b,123'
result = fullmatch(re_str, 'abc,123')
print(result)
re_str = r'a\b.b'
result = fullmatch(re_str, 'a,b')
print(result)
2) \B 检测是否 非单词边界
re_str = r'a.\Bb'
result = fullmatch(re_str, 'adb')
print(result)
3) ^ 检查是否是字符串开头
需放在正则表达式前面
re_str = r'^\d\d\d'
result = fullmatch(re_str, '123')
print(result)
re_str = r'^\d\d\d' '
result = search(re_str, '123')
print(result)
re_str = r'^\d\d\d'
result = search(re_str, 'sjhs是276鲨大富豪shj345')
print(result) # None
4) $ 检测是否是字符串结尾
需放在正则表达式后面
re_str = r'\d\d\d'
result = search(re_str, 'sjhs是276鲨大富豪shj345')
print(result) # '276'
re_str = r'\d\d\d$'
result = search(re_str, 'sjhs是276鲨大富豪shj345')
print(result) # '345'
5,正则匹配次数符号
包含: * + ? {}
1) *星号 匹配0次或多次
a* 匹配任意多个字符a
\d* 匹配任意多个\d数字字符
from re import fullmatch
# 导入re模块
re_str = r'1a*2'
result = fullmatch(re_str, '1aaa2')
print(result)
re_str = r'a\d*b'
result = fullmatch(re_str, 'a123456b')
print(result)
re_str = r'1[abc]*2'
result = fullmatch(re_str, '1abac2')
print(result)
2) +加号 匹配1次或多次,且加号不能匹配0次
re_str = r'1a+2'
result = fullmatch(re_str, '1aaa2')
print(result)
3) ? 问号 匹配0次或1次
re_str = r'a?\d\d'
result = fullmatch(re_str, 'a23')
print(result)
# 练习:写一个正则表达式能够匹配任意整数字符串,包括:6723、+23、-2891
from re import fullmatch
re_str = '.+'
result = fullmatch(re_str, '-2891')
print(result)
re_str = r'[-+]?\d+'
result = fullmatch(re_str, '-2891')
print(result)
4) {} 大括号
{N} 匹配N次
{M,N} 匹配M到N次 {0,1}?
{M,} 匹配至少M次 {0,}* {1,}==+
{,N} 最多匹配N次
re_str = r'\d{3}'
result = fullmatch(re_str, '891')
print(result)
re_str = r'a\d{2,5}b'
result = fullmatch(re_str, 'a7042b')
print(result)
5)贪婪和非贪婪
在匹配次数不确定的时候匹配模式分为贪婪和非贪婪
贪婪符号:? + * {M,N} {M,} {,N}
在能匹配成功的情况下尽可能多的去匹配
程序默认贪婪
例如匹配1次、3次和4次都能匹配成功,取4次
非贪婪:在能匹配成功的情况下尽可能少的去匹配
例如匹配1次、3次和4次都能匹配成功,取1次
*贪婪模式变非贪婪模式:?? +? ? {M,N}? {M,}? {,N}?
在匹配次数不定的次数后加?,就变成非贪婪模式
from re import fullmatch, search, findall
re_str = r'a.+b'
result = search(re_str, '手机号ashb还是你b黄寺b大街')
print(result) # 'ashb还是你b黄寺b'
re_str = r'a.+?b'
result = search(re_str, '手机号ashb还是你b黄寺b大街')
print(result) # 'ashb'
re_str = r'a\d{2,5}?b'
result = search(re_str, '手机号a278b还是你b黄寺b大街')
print(result) # 'a278b'
# 获取疫情信息国家名
with open('files/data.txt', 'r', encoding='utf-8') as f:
content = f.read()
re_str = r'"provinceName":".+?"'
print(findall(re_str, content))
6,正则的转义符号:
1) 符号前加\
在具有特殊功能或者特殊意义的符号前加
让符号原来的功能和意义消失,从而表示符号本身
re_str = r'abc\.'
print(fullmatch(re_str, 'abc.'))
re_str = r'abc\+'
print(fullmatch(re_str, 'abc+'))
re_str = r'\(\d{3}\)'
print(fullmatch(re_str, '(234)'))
2) 符号放在[]里面
具有特殊意义和功能的独立符号,放在[]里面,对应的功能会自动消失
包含: + ? * $ ^(不放在最前面) |
re_str = r'abc[.\]+?*$^(]'
print(fullmatch(re_str, 'abc]'))
7,正则的分组和分支
1)分组
用括号将正则的一部分看成一个组,来进行整体操作
from re import fullmatch, findall
用法一:看成一个整体进行操作
'67abc89abc34abc'
re_str = r'\d{2}[a-z]{3}\d{2}[a-z]{3}\d{2}[a-z]{3}'
print(fullmatch(re_str, '67abc89abc34abc'))
re_str = r'(\d{2}[a-z]{3}){3}'
print(fullmatch(re_str, '67abc89abc34abc'))
用法二:整体重复
在包含分组的正则中,可以通过\N来重复前面第N个分组匹配到的内容
re_str = r'a(\d{2})=\1'
print(fullmatch(re_str, 'a97=97'))
re_str = r'a(\d{2})=\1{2}'
print(fullmatch(re_str, 'a97=9797'))
re_str = r'([a-z]+)=(\d{2,4})=\2\1'
print(fullmatch(re_str, 'ak=879=879ak'))
用法三:捕获(只针对findall有效)
re_str = r'tel:(\d{5})'
print(findall(re_str, 'tel:23768, name:xiaoming, age:18岁,id:27237486; tel:72891, name:张三, age:67岁, id:23479782'))
2)分支 |
r’正则表达式1|正则表达式2’
先用正则1匹配,如果失败再用正则2匹配
# abc234、abcKLH
# abc\d{3} 、abc[A-Z]{3}
re_str = 'abc\d{3}|abc[A-Z]{3}' # abc234、abcKLH
print(fullmatch(re_str, 'abcMKL'))
re_str = r'abc\d{3}|[A-Z]{3}' # abc234、KMN
print(fullmatch(re_str, 'KSM'))
re_str = r'abc(\d{3}|[A-Z]{3})' # abc234、abcKLH
print(fullmatch(re_str, 'abc678'))