1,异常捕获
什么是异常:程序运行的时候报错了,就是我们程序出现了异常,程序会在异常的地方直接结束,不会往后继续执行。
list1 = [10, 20, 30]
print(list1[3]) # IndexError: list index out of range 此处报错,程序直接结束。
print('========')
异常捕获:当程序出现异常的时候,程序不崩溃还可以接着执行后面的代码。
异常捕获的用途:知道程序的某个地方可能会出现异常,但是代码没有问题(用户的不当操作造成),这个时候就可以使用异常捕获。
异常捕获语法:
"""
语法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
...
finally:
代码段3
"""
try:
age = int(input('请输入年龄:')) # 输入的年龄能转换成整数,否则返回 age = 0
print('****')
except:
print('年龄输入有误')
age = 0
print(f'年龄是:{age}')
print('+++++++++++')
# 练习:打开指定的文本文件,如果文件存在就读文件中的内容,如果不存在就创建这个文件。
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
关键字finally: finally的存在不影响原来异常捕获的执行,finally后面的代码是不管try里面的代码发生了什么情况都会执行。
try:
print('hello world!')
print('abc'[100]) # 下标错误,没有被捕获,执行print('写遗书')后程序结束。
print({'a': 19}['b'])
except IndexError:
print('出现了异常!')
finally:
print('写遗书')
2,正则匹配符号
正则表达式: 是让复杂的字符串处理变得更加简单的工具。
正则语法:
fullmatch(正则表达式, 字符串) - 判断指定的字符串是否满足正则表达式描述的规则,如果不满足返回None
python中正则表达式是写到单引号或者双引号里面,例如:‘正则表达式’;js中正则表达式是放在两个/之间的,例如:/正则表达式/
from re import fullmatch
# 1) 普通字符
# 普通字符指的是正则表达式中除了特殊符号以外的符号都是普通字符
# 普通字符在正则中表示这个符号本身。
# 2) . - 匹配一个任意字符
# 规则:一个字符串有3个字符,第一个字符是a,最后一个字符是c,中间是任意字符
re_str = 'a.c'
result = fullmatch(re_str, 'a胡c')
print(result)
# 练习:写一个正则能够匹配一个字符串的开头是1结尾是2,中间两个任意字符
result = fullmatch('1..2', '1就=2')
print(result)
# 3) \d - 匹配一个任意数字
# 规则:一个字符有4个字符,第一个字符是a,最后一个字符是b,中间是两个任意数字
re_str = r'a\d\db'
result = fullmatch(re_str, 'a49b')
print(result)
# 4) \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)
# 6)\S - 匹配任意一个非空白字符
# 规则:一个字符串有5个字符,第一个字符是数字,第二个字符不是空白字符,后面是abc
re_str = r'\d\Sabc'
result = fullmatch(re_str, '8=abc')
print(result)
# 7) [字符集] - 匹配字符集中任意一个字符
"""
[abc你] - 能匹配'a'或者'b'或者'c'或者'你'
[a\dbc] - 能匹配'a'或者'b'或者'c'或者任意一个数字
[1-9] - 匹配1到9中任意一个字符
[a-z] - 匹配任意一个小写字母
[A-Z\d] - 匹配任意一个大写字母或者任意一个数字
[a-zA-Z] - 匹配任意一个字母
[\u4e00-\u9fa5] - 匹配任意一个中文
[abc-] - 能匹配'a'或者'b'或者'c'或者'-'
注意:
1. 一个[]只能匹配到一个字符
2. -如果在两个字符之间表示范围,这个-前面的字符的编码值必须小于-后面的字符的编码值
3. -如果不在两个字符之间,表示-本身
"""
re_str = r'1[a=bc0]2'
result = fullmatch(re_str, '1=2')
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'
result = fullmatch(re_str, 'a5b')
print(result)
# 练习:写一个正则表达式匹配一个字符:123前面是一个数字、字母或者下划线
re_str = r'[\da-zA-Z_]123'
result = fullmatch(re_str, '_123')
print(result)
# 8) [^字符集] - 匹配不在字符集中的任意一个字符
"""
[^abc] - 匹配一个除了'a'、'b'、'c'以外的任意字符
[^a-zA-Z] - 匹配任意一个非字母字符
"""
re_str = r'[^abc]123'
result = fullmatch(re_str, 'A123')
print(result)
3,正则检测类符号
匹配类符号(一个符号必须匹配一个对应的字符):普通字符、.、\d、\s、\D、\S、[字符集]、[^字符集]
检测类符号:检测符号所在的位置是否符号要求(检测类的符号不影响匹配)
# 1.\b - 检测是否是单词边界
# 单词边界:所有可以划分出两个不同单词的符号,包括空白、标点符号、字符串开头或者结尾
re_str = r'abc\b,123\b'
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, 'apb')
print(result)
# 3.^ - 检测是否是字符串开头
re_str = r'^\d\d\d'
result = fullmatch(re_str, '627')
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'
4,匹配次数
# 1. * - 匹配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, 'a2334525398b')
print(result)
re_str = r'1[abc]*2'
result = fullmatch(re_str, '1abac2')
print(result)
# 2. + - 匹配1次或者多次
re_str = r'1a+2'
result = fullmatch(re_str, '1aaaaa2')
print(result)
# 3. ? - 匹配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, '-23')
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, '780')
print(result)
re_str = r'a\d{2,5}b'
result = fullmatch(re_str, 'a7042b')
print(result)
# 5.贪婪和非贪婪
# 在匹配次数不确定的时候匹配模式分别贪婪和非贪婪
# 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, '手机号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))
5,分支和分组
from re import fullmatch,findall
# 1.分组 - 用()将正则的一部分括起来看成一个整体进行操作
# 用法一:看成一个整体进行操作
# '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'))
6,转义字符
from re import fullmatch
# 正则的转义符号:在具有特殊功能或者特殊意义的符号前加\,让符号原来的功能和意义消失,表示符号本身
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)'))
# 具有特殊意义和功能的独立的符号,放在[]里面,对应的功能会自动消失,例如:+、?、*、$、^(不放在最前面)、|等
re_str = r'abc[.\]+?*$^(]'
print(fullmatch(re_str, 'abc]'))