异常捕获和正则
1.异常捕获
-
什么是异常:程序运行的时候报错了,我们程序出现了异常
程序异常的后果:程序会在异常的地方直接结束,不会往后继续执行list1 = [10, 20, 30] print(list1[3]) # IndexError: list index out of range
-
目的:当程序出现异常的时候,程序不崩溃还可以接着执行后面的代码
什么时候需要捕获:明明知道某个地方会出现异常,但是代码没有问题(用户的不当操作),这个时候就可以使用异常捕获-
语法1: - 捕获所有类型的异常
try:
代码段1
except:
代码段2
finally:
代码段3 -
说明:
try、except - 关键字;固定写法
代码段1 - 需要捕获异常的代码
代码段2 - 捕获到异常后会执行的代码 -
执行过程:先执行try后面的代码段1,如果没有异常,直接执行后面的其他代码(不会执行代码段2);
如果代码段1在执行的时候出现异常,程序不崩溃,直接(马上)执行except后面的代码段2 -
语法2: - 获取指定类型的异常
try:
代码段1
except 异常类型:
代码段2
finally:
代码段3 -
语法3: - 同时捕获多种异常,针对不同异常进行相同处理
try:
代码段1
except(异常类型1,异常类型2,…):
代码段2
finally:
代码段3 -
语法4: - 同时捕获多种异常,针对不同异常进行不同处理
try:
代码段1
except 异常类型1:
代码段11
except 异常类型2:
代码段22
except 异常类型3:
代码段33
finally:
代码段4
try: age = int(input('请输入年龄:')) print('*******') except: print('年龄输入有误') age = 0 print(f'年龄是:{age}') print('++++++++++++')
-
练习:打开指定文本文件,如果文件存在就读取文件中的内容,如果不存在就创建这个文件
try:
with open('./hh.txt', 'r', encoding='utf-8') as f:
context = f.read()
except:
with open('./hh.txt', 'w', encoding='utf-8') as f:
f.write('')
print(context)
try:
list1 = [10, 20, 30]
print(list1[3])
print({'a': 10, 'b': 20}['aa'])
except IndexError:
print('列表越界出现异常')
-
关键字finally
- finally的存在不影响原来异常捕获的执行
- finally后面的代码不管是try里面的代码发生了什么情况都会执行。(就算代码段1出现异常没有被捕获到finally后面的代码也会执行)
try: print('hello world!') # print('abc'[100]) print({'a': 190}['b']) except IndexError: print('出现了异常') finally: print('写遗书')
2. 正则匹配符号
-
什么是正则表达式
正则表达式是让复杂的字符串处理变得更加简单的工具 -
正则语法
- fullmatch(正则表达式,字符串) - 判断指定的字符串是否满足正则表达式描述的规则,如果不满足返回None
- python中正则表达式是写到单引号或者双引号里面,例如:‘正则表达式’;js中正则表达式是放在两个/之间的,例如:/正则表达式/
1)普通字符
普通字符指的是正则表达式中除了特殊符号以外的符号都是普通字符,普通字符在正则中表示这个符号本身。# 规则:一个字符串有3个字符,第一个字符是a,第二个字符是b,第三个字符是c re_str = 'abc' result = fullmatch(re_str, 'abc') print(result)
2). - 匹配一个任意字符
# 规则:一个字符串有3个字符,第一个字符是a,最后一个字符是c,中间是任意字符 re_str = 'a.c' result = fullmatch(re_str, 'a胡c') print(result)
练习:写一个正则能够匹配一个字符串的开头是1结尾是2,中间两个任意字符
result = fullmatch('1..2', '1sd2') print(result)
- \d - 匹配一个任意数字
# 规则:一个字符有4个字符,第一个字符是a,最后一个字符是b,中间两个任意数字 re_str = r'a\d\db' # 加r是防止被转义 result = fullmatch(re_str, 'a56b') print(result)
- \s - 匹配一个任意空白字符
空白字符:空格、\n、\t
# 规则:一个字符串开头是两个数字,中间一个空白,然后再两个数字 re_str = r'\d\d\s\d\d' result = fullmatch(re_str, '23 89') print(result)
5)\D - 匹配任意一个非数字字符
# 规则:一个字符串有4个字符,第一个字符不是数字,后面是abc re_str = r'\Dabc' result = fullmatch(re_str, '=abc') print(result)
- \S - 匹配任意一个非空白字符
# 规则:一个字符串有5个字符,第一个字符是数字,第二个字符不是空白字符,后面是abc re_str = r'\d\Sabc' result = fullmatch(re_str, '9.abc') print(result)
7)[字符集] - 匹配字符集中任意一个字符
- [abc你] - 能匹配’a’或者’b’或者’c’或者’你’
- [abc\d] - 能匹配’a’或者’b’或者任意一个数字
- [1-9] - 匹配1到9中任意一个字符
- [a-z] - 匹配任意一个小写字母
- [A-Z\d] - 匹配任意一个大写字母或任意一个数字
- [a-zA-Z] - 匹配任意一个字母
- [\u4e00-\u9fa5] - 匹配任意一个中文
- [abc-] - 匹配’a’或者’b’或者’c’或者’-’
- 注意:
- 一个[]只能匹配到一个字符
- -如果在两个字符之间表示范围,这个-前面的字符的编码值必须小于-后面的字符的编码值
- -如果不在两个字符之间,表示-本身
from re import fullmatch re_str = r'1[a=b0c]2' result = fullmatch(re_str, '1=2') print(result) re_str = r'1[\dxy哈]2' result = fullmatch(re_str, '1哈2') print(result) # re_str = r'a[2345678]b' re_str = r'a[2-8]b' result = fullmatch(re_str, 'a8b') print(result)
- [ ^字符集] - 匹配不在字符集中的任意一个字符
[ ^abc] - 匹配一个除了’a’、‘b’、'c’以外的任意字符
[ ^a-zA-Z] - 匹配任意一个非字母字符from re import fullmatch re_str = r'[^abc]123' result = fullmatch(re_str, 'A123') print(result)
练习:写一个正则表达式匹配一个字符:123前面是数字、字母或者下划线
re_str = r'[\da-zA-Z_]123'
result = fullmatch(re_str, '_123')
print(result)
3.正则检测类符号
匹配类符号(一个符号必须匹配一个对应的字符):普通字符、.、\d、\s、\D、\S、[字符集]、[ ^字符集]
检测类符号:检测符号所在的位置是否符合要求
注意:检测类的符号不影响匹配
- \b - 检测是否是单词边界
单词边界:所有可以划分出两个不同单词的符号,包括空白、标点符号、字符串开头或者结尾
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)
-
\B - 检测是否是非单词边界
re_str = r'a.\Bb' result = fullmatch(re_str, 'acb') print(result)
-
^ - 检测是否是字符串开头
re_str = r'^\d\d\d' result = fullmatch(re_str, '627') print(result) re_str = r'^\d\d\d' result = search(re_str, 'sdad带我飞sdw215') print(result) # None
-
$ - 检测是否是字符串结尾
re_str = r'\d\d\d' result = search(re_str, 'sdad带我飞264sdw215') print(result) # 264 re_str = r'\d\d\d$' result = search(re_str, 'sdad带我飞sdw215') print(result) # 215
4.匹配次数
- . * 匹配0次或多次
a* - 匹配任意多个字符a
\d* - 匹配任意多个\d(任意多个任意数字字符)
re_str = r'1a*2'
result = fullmatch(re_str, '1aaa2')
print(result)
re_str = r'a\d*b'
result = fullmatch(re_str, 'a251513b')
print(result)
re_str = r'1[abc]*2'
result = fullmatch(re_str, '1aabbb2')
print(result)
- +: 匹配1次或者多次
re_str = r'1a+2'
result = fullmatch(re_str, '1aa2')
print(result)
- ? : 匹配0次或者1次
re_str = r'-?\d\d'
result = fullmatch(re_str, '-23')
print(result)
练习:写一个正则表达式能够匹配任意整数字符串,包括:6723、+23、-2891
re_str = r'[+-]?\d+'
result = fullmatch(re_str, '+6231')
print(result)
-
{}
-
{N} - 匹配N次
-
{M,N} - 匹配M到N次 {0,1} == ?
-
{M,} - 匹配至少M次 {0,} == * {1,} == +
-
{,N} - 匹配至多N次
re_str = r'\d{7}' result = fullmatch(re_str, '2468569') print(result) re_str = r'a\d{2,5}b' result = fullmatch(re_str, 'a702b') print(result)
-
-
贪婪和非贪婪
在匹配次数不确定的时候匹配分别贪婪和非贪婪
1)贪婪:在能匹配成功的前提下尽可能多的去匹配,例如匹配1次、3次和4次都能匹配成功,最后取4次。
默认情况下,所有的不确定次数匹配的时候都是贪婪的:*、+、?、{M,N}、{M,}、{,N}
2)非贪婪:在能匹配成功的前提下尽可能少的去匹配,例如匹配1次、3次和4次都能匹配成功,最好取1次。
在匹配次数不定的次数后加?,就变成非贪婪模式 *?、+?、??、{M,N}?、{M,}?、{,N}?re_str = r'a.+b' result = search(re_str, '速度asdb烦恼歌b放几天') print(result) # asdb烦恼歌b re_str = r'a.+?b' result = search(re_str, '速度asdb烦恼歌b放几天') print(result) # asdb
5.分支和分组
-
分组 - 用()将正则的一部分括起来看成一个整体进行操作
# 用法一:看成一个整体进行操作 # '67abc89abc34abc' re_str = r'\d{2}[a-z]{3}\d{2}[a-z]{3}\d{2}[a-z]{3}' print(fullmatch(re_str, '67abc89abc34abc'))
# 用法二:整体重复 # 在包含分组的正则中,可以通过\N来重复前面第N个分租匹配到的内容 re_str = r'a(\d{2})\1' print(fullmatch(re_str, 'a7878')) 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=520=520ak'))
# 用法三:捕获(只针对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:27237477'))
-
分支 - /
re_str = r'abc\d{3}|abc[A-Z]{3}' print(fullmatch(re_str, 'abcMKL')) # abc234、abcKLH re_str = r'abc\d{3}|[A-Z]{3}' print(fullmatch(re_str, 'KSM')) # abc234、KSM re_str = r'abc(\d{3}|[A-Z]{3})' print(fullmatch(re_str, 'abc234')) # abc234、abcKLH
6.转义符号
-
正则的转义符号:在具有特殊功能或者特殊意义的符号前加\,让符号原来的功能和意义消失,表示符号本身
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, '(123)'))
-
具有特殊意义和功能的独立的符号,放在[]里面,对应的功能会自动消失,例如:+、?、*、$、^(不放在最前面)、|等
re_str = r'abc[.\]+?*$^(]' print(fullmatch(re_str, 'abc]'))