Day27 正则表达式
文章目录
1、正则表达式概述
正则表达式不属于任何一门编程语言,主要作用于数据的查找与筛选
正则表达式的本质:
正则表达式本质就是使用一些符号组合产生一些特殊含义,然后去字符串中筛选出符合条件的数据
2、正则表达式之字符组
正则表达式中字符组 在没有量词修复的情况下一次筛选只会针对一个数据值
常见的正则表达式字符组用法
字符组 | 功能 |
---|---|
[0-9] | 匹配0到9之间的任意一个数字(包括0和9) |
[A-Z] | 匹配A到Z之间的任意一个字母(包括A和Z) |
[a-z] | 匹配a到z之间的任意一个字母(包括a和z) |
[0-9a-zA-Z] | 匹配数字,小写字母、大写字母都可以 |
3、正则表达式之特殊符号
正则表达式 中特殊符号在没有量词修饰的情况一个符号一次只会针对一个数据值
常用的特殊符号
特殊符号 | 功能 |
---|---|
. | 匹配除换行符外的任意字符 |
\w | 匹配字母 数字 下划线 |
\W (大写W) | 匹配字母或数字或下划线 |
\d | 匹配数字 |
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
^a$ | ^号与$一起使用能够明确限制想要查找的具体数据 |
``a | b`` |
() | 用于正则表达式的分组 不影响正则表达式的匹配 |
[] | 匹配字符中字符 |
[^] | 匹配字符组中字符的所有数据 |
4、正则表达式之量词
在正则表达式中所有的量词默认都是贪婪匹配(尽可能多的匹配)
量词不能单独使用必须跟在表达式后面 并且只能影响紧挨着的左边那一个
量词
量词符号 | 功能 |
---|---|
* | 重复零次或更多次(默认尽可能的多) |
+ | 重复一次或多次(默认就是尽可能多) |
? | 重复零次或一次(默认为1次) |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
4.1、正则表达式 特殊符与量词使用练习
表达式 | 匹配文本 | 取值结果 |
---|---|---|
海. | 海燕海娇海东 | [海燕,海娇,海东] |
^海. | 海燕海娇海东 | [海燕] |
海.$ | 海燕海娇海东 | [海东] |
李.? | 李杰和李莲英和李二棍子 | [李杰,李莲,李二] |
李.* | 李杰和李莲英和李二棍子 | [李杰和李莲英和李二棍子] |
李.+ | 李杰和李莲英和李二棍子 | [李杰和李莲英和李二棍子] |
李.{1,2} | 李杰和李莲英和李二棍子 | [李杰和,李莲英,李二棍] |
李[杰莲英二棍子]* | 李杰和李莲英和李二棍子 | [李杰,李莲英,李二棍子] |
李[^和]* | 李杰和李莲英和李二棍子 | [李杰,李莲英,李二棍子] |
[\d] | 456bdha3 | [4,5,6,3] |
[\d]+ | 456bdha3 | [456,3] |
5、贪婪匹配与非贪婪匹配
所有量词默认都是贪婪匹配,但是如果在量词后面紧跟一个问号
那么就会变成非贪婪匹配
小技巧
以后我们在使用贪婪匹配或者非贪婪匹配的时候一般都是用
.*
或者.*?
并且在哪结束可以由上诉符号左边两边添加表达式决定
5.1、贪婪匹配举例
#匹配文本
<script>alert(123)</script>
#正则表达式
<.*>
>>>>>>>>>>>>>>>>>>>>>>>>
['<script>alert(123)</script>']
5.2、非贪婪匹配
#匹配文本
<script>alert(123)</script>
#正则表达式
<.*?>
>>>>>>>>>>>>>>>>>>>>>>
['<script>', '</script>']
6、正则表达式取消转义
正则表达式中 有时候斜杠与字母组合存在特殊含义,通过在斜杠前面加斜杠就可以转义
表达式 | 取消转义 |
---|---|
\n | \\n |
\\n | \\\\\n |
- 以此类推
在python中可以通过直接引号前面加 r
来取消转义
正则表达式 | 取消转义后 |
---|---|
'\n' | r'\n’ |
'\\n' | r'\\n' |
作业
完善购物车功能
查看购物车
移除购物车商品
修改购物车数量
…
ps:写完后 优化代码结构(省代码 封函数等)
import os
import json
# 根目录
path_root = os.path.dirname(os.path.dirname(__file__))
# 存储用户数据的目录
path_db = os.path.join(path_root, 'db')
# 判断 db目录是否存在 不存在直接创建
if not os.path.exists(path_db):
os.makedirs(path_db)
# 登录状态
online_user = {'name': None}
# 全局临时购物车
online_chop_car = {}
# {"balance":15000,"shop_car":{'极品木瓜':[个数,单价]}}
good_list = [
['挂壁面', 3],
['印度飞饼', 22],
['极品木瓜', 666],
['土耳其土豆', 999],
['伊拉克拌面', 1000],
['董卓戏张飞公仔', 2000],
['仿真玩偶', 10000]
]
# 校验用户登录的装饰器
def decorator(func_1):
def other(*args, **kwargs):
# 判断全局是否有在线用户
if online_user['name']:
res = func_1(*args, **kwargs)
return res
# 如果判断为False 则先登录
else:
if log():
res = func_1(*args, **kwargs)
return res
return other
# {"name":"jason","pwd":123,"balance":15000,"shop_car":{}}
# 注册功能
def reg():
while True:
print('账户注册/返回请按0'.center(40, '-'))
reg_name = input('regname>>>')
path_user = os.path.join(path_db, reg_name + '.json')
if reg_name == '0':
break
elif os.path.exists(path_user):
print('账号已存在')
continue
else:
reg_pwd = input('regpassword>>>')
reg_pwd_1 = input('regpassword_again>>>>')
if reg_pwd != reg_pwd_1:
print('密码两次输入不一致')
continue
user_dict = {"name": reg_name, "pwd": reg_pwd, "balance": 15000, "shop_car": {}}
with open(path_user, 'w', encoding='utf')as user_w:
json.dump(user_dict, user_w)
print('注册成功')
return
# 登录功能
def log():
while True:
print('账户登录/返回请按0'.center(40, '-'))
log_name = input('logname>>>').strip()
# 建立该用户 的路径
path_user = os.path.join(path_db, log_name + '.json')
# 判断退出
if log_name == '0':
return
# 判断该用户文件是否存在
elif os.path.exists(path_user):
log_pwd = input('logpassword>>>').strip()
# 读取该文件内容
with open(path_user, 'r', encoding='utf')as user_r:
# 获取用户信息字典
user_info_dict = json.load(user_r) # "name":reg_name,"pwd":reg_pad,"balance":15000,"shop_car":{}
if user_info_dict.get('pwd') == log_pwd:
# 修改全局 在线用户
online_user['name'] = log_name
print('登录成功')
return True
else:
print('密码错误')
else:
print('账号不存在')
# 添加商品至购物车
@decorator
def shopping():
# 获取 现用户 文件地址
path_user = os.path.join(path_db, online_user["name"] + '.json')
# 格式化打印 商品信息 顺便加个 索引同值的 商品编号
while True:
for i, goods in enumerate(good_list):
print(f'|{i}|商品:{goods[0]} 单价:{goods[1]}$')
# 用户选择需要的商品编号
choose_user = input('请输入想要购入的商品编号 返回请输入 ').strip()
# 判断输入是否为数字
if not choose_user.isdigit():
print('请输入数字的商品编号')
continue
# 将输入转为数字
choose_user = int(choose_user)
# 确保输入在编号之内的整数
if choose_user > i:
print('无此商品')
continue
# 用户选择要购买的数量
goods_number = input('请输入购买的数量').strip()
if goods_number.isdigit():
goods_number=int(goods_number)
# 获取商品信息
goods_info_list = good_list[choose_user]
# 获取商品名
goods_name = goods_info_list[0]
# 获取商品单价
goods_price = goods_info_list[1]
# 放入全局临时购物车 shop_car":{'极品木瓜'-:[个数,单价]}}
online_chop_car[goods_name] = [goods_number, goods_price]
#每次添加购物车直接写入
mod(goods_name)
# 写一次把全局重置
del online_chop_car[goods_name]
print('添加成功')
if input('继续添加按任意键 返回请按 0\n>>>')=='0':
break
# 查看 管理购物车
@decorator
def shopping_car():
path_user=os.path.join(path_db, online_user["name"] + '.json')
while True:
with open(path_user, 'r', encoding='utf')as user_r:
# 文件中取出购物车
data=json.load(user_r)
user_car=data['shop_car']
#判断 没东西的话 直接踢出去
if not user_car:
print('购物车为空')
break
#创建一个临时存放键值的列表
goods_name_list=[]
#打印购物
print('购物车'.center(30,'='))
# 打印商品所有信息
for i,goods_name in enumerate(user_car):
goods_info=user_car[goods_name]
#添加商品名至 空列表
goods_name_list.append(goods_name)
print(f'|{i}| 商品:{goods_name} 数量:{goods_info[0]} 单价:{goods_info[1]} $')
print(31*'=')
if input('1.管理商品 0.返回\n>>>')=='1':
choose_car=input('请输入您要编辑的商品编号>>>')
if choose_car.isdigit():
choose_car = int(choose_car)
else:
print('输数字')
continue
goods_number=input('请输入您要调整的个数 移除该商品请按 0\n>>>').strip()
if goods_number.isdigit():
goods_number = int(goods_number)
else:
print('输数字大哥')
# 当要删除商品时
if goods_number==0:
del user_car[goods_name_list[choose_car]]
else:
# 通过列表名 获取商品名 然后作为键获取 对应商品信息
goods_info=user_car[goods_name_list[choose_car]]
goods_info[0]=goods_number
print('正常')
with open(path_user,'w',encoding='utf')as user_w:
json.dump(data,user_w,ensure_ascii=False)
user_w.flush()
print('修改成功')
if input('继续按任意键\n返回请按 0\n>>>') =='0':
return
else:
return
# 结算购物车
@decorator
def settlement():
path_user = os.path.join(path_db, online_user["name"] + '.json')
while True:
with open(path_user, 'r', encoding='utf')as user_r:
# 文件中取出购物车
data=json.load(user_r)
user_car=data['shop_car']
user_balance=data['balance']
# 判断 没东西的话 直接踢出去
if not user_car:
print('购物车为空')
break
# 创建一个临时存放键值的列表
goods_name_list = []
print(f'余额:{user_balance}$')
# 打印购物
print('购物车'.center(30, '='))
# 打印商品所有信息
price=0
for i, goods_name in enumerate(user_car):
goods_info = user_car[goods_name]
# 添加商品名至 空列表
goods_name_list.append(goods_name)
print(f'|{i}| 商品:{goods_name} 数量:{goods_info[0]} 单价:{goods_info[1]} $')
goss_price=goods_info[0]*goods_info[1]
price+=goss_price
print(f'购物车总需支付{price}$')
if input('1.结账\n0.返回\n>>>')=='1':
if user_balance<price:
print('余额不足')
break
else:
new_user_balance=user_balance-price
else:
return
data['balance']=new_user_balance
data['shop_car']={}
with open(path_user,'w',encoding='utf')as user_w:
json.dump(data,user_w)
print('支付成功')
return
# 文件修改工具
def mod(goos_name):
# 文件路径
path_user = os.path.join(path_db, online_user['name'] + '.json')
with open(path_user, 'r', encoding='utf')as user_r:
# #读取用户 数据
data_1 = json.load(user_r)
# 获取文件购物车
data_3 = data_1['shop_car']
# 当临时购物车中的商品名 在文件购物车中出现过时
if goos_name in data_3:
# 获取临时购物车中 商品个数
online_good_number = online_chop_car.get(goos_name)[0]
# 获取 文件中 商品信息
txt_good_info=data_3[goos_name]
#将文件中的 商品信息列表 中的个数自增
txt_good_info[0]+=online_good_number
else:
# 正常情况
data_3[goos_name] = online_chop_car.get(goos_name)
#更新后的 字典
data_1['shop_car']=data_3
with open(path_user, 'w', encoding='utf')as user_w:
#更新至文件
json.dump(data_1,user_w,ensure_ascii=False)
return
# 退出登录
def log_out():
online_user['name']=None
print('退出登录成功')
choose_funce_diict={'1':reg,
'2':log,
'3':shopping,
'4':shopping_car,
'5':settlement,
'6':log_out}
while True :
print('购物系统'.center(50,'+'))
choose=input('1.注册账户\n2.登录账户\n3.购买商品\n4.管理购物车\n5.结算购物车\n6.退出登录\n0.退出系统\n>>>')
if choose in choose_funce_diict:
choose_funce_diict[choose]()
elif choose=='0':
print('退出系统')
break
else:
print('无此选项')