【千锋Python2205班10.13笔记-day16-模块和异常(一阶段)】

01-review

1. 数据持久化

2. 文件操作基本步骤

打开文件 -> 读写操作 -> 关闭文件

open(文件路径, 打开方式, *, 文本文件编码方式)

r、w、a

文件对象.read()、文件对象.readline()

文件对象.write()

文件对象.close()

with open('files/test.txt', 'r', encoding='utf-8') as f:
    f.read()

2. 数据持久化的步骤

1)第一步:确定需要持久化的数据

2)第二步:设计文件和文件内容

3)第三步:程序中需要数据的时候从文件中读数据;数据发生了改变需要把最新的数据更新到文件中。

02-注册登录系统

import os

"""
注册过的账号的持久化策略:
1. 数据保存在哪个文件中(位置和名字):  files/userinfo.txt
2. 以什么样的形式将数据保存在文件中:
[{'username': 'xiaoming', 'pw': '123456'}, ]

"""


def register():
    # 1.提示用户输入账号和密码
    account = input('请输入账号:')
    password = input('请输入密码:')

    # 2.检测输入的账号是否已经注册
    # 1)获取之前已经注册过的所有的账号
    try:
        with open('files/userinfo.txt', 'r', encoding='utf-8') as f:
            all_user = eval(f.read())
    except FileNotFoundError:
        all_user = []

    # 2)判断输入的用户名是否注册过
    for x in all_user:
        if x['username'] == account:
            print('注册失败!该账号已经注册过!')
            return

    # 3.保存注册成功的账号和对应的密码
    all_user.append({'username': account, 'pw': password})
    with open('files/userinfo.txt', 'w', encoding='utf-8') as f:
        f.write(str(all_user))
    print('注册成功!')


def login():
    # 1.提示用户输入账号和密码
    account = input('请输入账号:')
    password = input('请输入密码:')

    # 2.检测是否登录成功
    # 1)看输入的账号是否已经注册(先获取所有已经注册过的账号信息)
    # 2)看输入的密码和注册的时候对应的密码是否一致
    if not os.path.exists('files/userinfo.txt'):
        print('登录失败!该账号没有注册过!')
        return

    with open('files/userinfo.txt', 'r', encoding='utf-8') as f:
        all_user = eval(f.read())
    for x in all_user:
        if x['username'] == account:
            if x['pw'] == password:
                print('登录成功!')
            else:
                print('登录失败!')
            return

    print('登录失败!')


def main_page():
    # 打印主页内容
    with open('files/mainpage.txt', encoding='utf-8') as f:
        page = f.read()

    while True:
        print(page)

        # 提示用户输入
        value = input('请选择(1~3):')

        # 根据用户的选择执行不同的功能
        if value == '1':
            login()
        elif value == '2':
            register()
        elif value == '3':
            return
        else:
            print('输入有误!')


if __name__ == '__main__':
    main_page()

03-认识正则表达式

1. 正则表达式的作用

正则表达式是一种可以让复杂的字符串问题变得简单的工具

问题:判断手机号是否合法

方法1:不使用正则

# tel = '182839202303'

# if len(tel) != 11:

#     print('不是合法的手机号')

# else:

#     for x in tel:

#         if not '0' <= x <= '9':

#             print('不是合法的手机号')

#             break

#     else:

#         if tel[0] != '1':

#             print('不是合法的手机号')

#         elif '3' <= tel[1] <= '9':

#             print('是合法的手机号')

#         else:

#             print('不合法')

方法2:

# tel = '13283920303'

# from re import fullmatch

# print(fullmatch(r'1[3-9]\d{9}', tel) != None)


# from re import split

# str2 = '23+45-89-1928*233'

# print(split(r'[+*-]', str2))

# 2.fullmatch函数

# fullmatch(正则表达式, 字符串)     -   判断字符串和正则表达式是否完全匹配(判断整个字符串是否符合正则表达式所描述的规则),如果不符合返回None

# python提供正则表达式的方式:直接将正则表示作为一个字符串内容(正则需要使用引号引起来,而且引号前面一般需要加r)

04-正则表达式语法

from re import fullmatch

写正则表达式都是通过正则符号来描述字符串规则

1. 匹配类符号 -

用来规定字符(用来描述对字符的要求)

###1)普通字符 -

除了特殊符号以外的符号都是普通字符(在正则中表示符号本身)

print(fullmatch(r'abc', 'abc'))

2) . - 匹配任意一个字符

print(fullmatch(r'a.c', 'a+c'))
print(fullmatch(r'a..c', 'a+和c'))

3)\d -

匹配任意一个数字字符

print(fullmatch(r'a\dc', 'a1c'))
print(fullmatch(r'\d\d\d', '728'))

4) \s -

匹配任意一个空白字符

空白字符:’ ‘、’\n’、‘\t’

print(fullmatch(r'\d\d\s\d', '23\t5'))

5) \w -

匹配任意一个数字、字母、下划线或者中文

print(fullmatch(r'a\wa', 'a_a'))

6) \D、\S、\W

\D - 匹配任意一个非数字字符

print(fullmatch(r'a\Dc', 'a框c'))

7)[字符集] -

匹配字符集中任意一个字符

用法1: 在[]中提供多个普通字符, 匹配多个字符中的任意一个
用法2:[字符1-字符2],匹配字符1到字符2范围中的任意一个字符

用法3:在[]中包含\开头的特殊符号
[\da-z]: 匹配任意一个数字或者任意一个小写字母
​ [\da-zA-Z_\u4e00-\u9fa5] == \w

注意:[]中的减号只有在两个字符之间的时候才表示谁到谁

print(fullmatch(r'a[mn1]b', 'a1b'))
print(fullmatch(r'a[2-5]c', 'a4c'))
print(fullmatch(r'abc[\u4e00-\u9fa5]', 'abc就'))
print(fullmatch(r'[-az]abc', '-abc'))

8)[^字符集] - 匹配不在字符集中的任意一个字符

2. 匹配次数

任何匹配类符号后面都可以添加匹配次数对应的符号来控制字符的个数

1) + -

匹配1次或者多次(至少1次)

print(fullmatch(r'a+', 'aaaaaa'))
print(fullmatch(r'\d+a', '8292333a'))
print(fullmatch(r'a.+b', 'amksk数据s--=2b'))
print(fullmatch(r'a[1-5]+b', 'a43b'))

2) * - 匹配0次或者多个(任意次数)

print(fullmatch(r'a\d*b', 'a2233b'))

3) ? -

匹配0次或者1次

print(fullmatch(r'-?abc', '-abc'))

4) {}

# {N}   -   N次

# {M,N}     -   M到N次

# {M,}      -   至少M次

# {,N}       -   最多N次

print(fullmatch(r'a\d{3}b', 'a783b'))
print(fullmatch(r'a\d{3,5}b', 'a345b'))
print(fullmatch(r'a\d{3,}b', 'a89233423b'))
print(fullmatch(r'a\d{,3}b', 'a232b'))

5)贪婪和非贪婪

如果匹配次数不确定,匹配的时候分为贪婪和非贪婪两种模式(默认是贪婪模式)

a.贪婪模式: 在多种匹配次数都可以匹配成功的时候,贪婪取最多的次数来进行匹配
b.非贪婪模式: 在多种匹配次数都可以匹配成功的时候,非贪婪取最少的次数来进行匹配
(在不确定的匹配次数后面再加一个?: +?、*?、??、{M,N}?、{M,}?、{,N}?)

from re import match, findall

# match(正则表达式, 字符串)  - 匹配字符串开头

print(fullmatch('\d{3}', '233'))
print(match(r'\d{3}', '728空间数据水电费'))



# 2 -> amnb

# 4 -> amnb还b

print(match(r'a.+b', 'amnb还b上课'))       # <re.Match object; span=(0, 6), match='amnb还b'>
print(match(r'a.+?b', 'amnb还b上课'))      # <re.Match object; span=(0, 4), match='amnb'>

print(match(r'a.+b', 'amnb还上课'))
print(match(r'a.+?b', 'amnb还上课'))

# print(findall(r'\d{3}', 'sjfh28393手机壳是否290shjf 283就开始900'))

message = '<jhsj28->数sssjs<992函数>kss<0-2=2-2033是>宿舍'
result = findall(r'<.+?>', message)
print(result)

3. 分组和分支

1)分组 - ()

分组就是用()将正则的部分内容括起来表示一个整体。
a. 整体控制(将正则中一部分内容括起来整体控制次数)
b. 重复(在正则中用\M来重复它前面第M个分组匹配到的结果)
c. 捕获(在获取匹配结果的时候可以自动(只有findall具有自动捕获的功能)或者手动的获取某个分组匹配的结果)

2)整体控制的案例

# '67kmn89ksm78kom'

# print(fullmatch(r'\d\d[a-z]{3}\d\d[a-z]{3}\d\d[a-z]{3}', '67kmn89ksm78kom'))

# print(fullmatch(r'\d\d[a-z]{3}', '67kmn89ksm'))

print(fullmatch(r'(\d\d[a-z]{3}){3}', '67kmn89ksm78kom'))
print(fullmatch(r'(\d\d[a-z]{3})+', '67kmn89jkm'))

3)重复的案例

# '23mnk23'、'89kms89'  -  匹配成功

# '23mnk45'    -  None

print(fullmatch(r'(\d\d)[a-z]{3}\1', '23mks23'))

print(fullmatch(r'(\d\d)ab([A-Z]{3})-\2', '23abMKN-MKN'))
print(fullmatch(r'(\d\d)ab([A-Z]{3})-\2\1', '23abMKN-MKN23'))
print(fullmatch(r'(\d\d)ab([A-Z]{3})-\1{3}mn\2', '23abMKN-232323mnMKN'))

4)自动捕获案例

message = '<jhsj28->数sssjs<992函数>kss<0-2=2-2033是>宿舍'
result = findall(r'<(.+?)>', message)
print(result)

message = '哈吉斯234元看sjsj38000k0===233元开始看82993'
result = findall(r'(\d+)元', message)
print(result)

4. 检测类符号

先匹配,匹配成功后再来看检测类符号所在的位置是否符合相关要求

1)\b -

检测是否是单词边界(单词边界指的是任何可以将两个单词区分开来的符号:空白符号、英文标点符号、字符串开头和字符串结尾)

2)^ -

检测是否是字符串开头

3)$ -

检测是否是字符串结尾

print(fullmatch(r'abc\bmn', 'abcmn'))

message = '23sksm7823数据接口,232米好9022 28323,82923美女990'
print(findall(r'\b\d+\b', message))

message = '23sksm7823数据接口,232米好9022 28323,82923美女990'
print(findall(r'^\d+', message))
print(findall(r'\d+$', message))

5. 转义符号 -

在具有特殊意义的符号前加’'让这个有特殊意义的符号变成一个普通符号

案例:匹配任意一个小数

print(fullmatch(r'\d+\.\d+', '23.34'))

‘34+23’

print(fullmatch(r'\d\d\+\d\d', '34+23'))

‘(234)’

print(fullmatch(r'\(\d{3}\)', '(345)'))

补充:除了\开头的特殊符号,其他符号放在[]中对应的特殊功能会自动消失

print(fullmatch(r'[.+\-?^\]]abc', ']abc'))

6.分支 - |

正则1|正则2|正则3|…

正则1|正则2

‘234’、‘mns’

print(fullmatch(r'\d{3}|[a-z]{3}', 'amn'))

‘abc234’、‘abcMKJ’

print(fullmatch(r'abc\d{3}|abc[A-Z]{3}', 'abcMJK'))
print(fullmatch(r'abc(\d{3}|[A-Z]{3})', 'abcMKS'))


from re import fullmatch, match, findall, split, search, sub, finditer

fullmatch(正则, 字符串) - 完全匹配

match(正则, 字符串) - 匹配字符串开头

findall(正则, 字符串) - 提取字符串中所有满足正则的子串,返回一个列表

split(正则, 字符串) - 将字符串中所有满足正则的子串作为切割点对字符串进行切割

search(正则, 字符串) - 匹配字符串中第一个满足正则的字符串

sub(正则, 字符串1, 字符串2) - 将字符串2中所有满足正则的子串都替换成字符串1

finditer(正则, 字符串) - 提取字符串中所有满足正则的子串; 返回一个迭代器,迭代器中的元素是匹配对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值