【python基础】第29回 正则表达式

正则表达式

1. 正则表达式简介

1.1 官方定义

正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。

1.2 理解

该知识点不属于任何一门编程语言,是一个独立的学科,主要用于数据的查找与筛选

1.3 总结

正则表达式本质上就是使用一些符号的组合产生一些特殊的含义,然后去字符串中筛选出符合条件的数据

1.4 比较

需求:编写代码校验用户输入的手机号是否合法
常见 13 15 17 18 19
# 纯python代码逻辑实现
# 1. 获取用户输入的手机号
phone_num = input('请输入您的手机号>>>:').strip()
# 2. 判断用户输入的手机号是否是纯数字
if phone_num.isdigit():
    # 3. 判断总长度是否是11位
    if len(phone_num) == 11:
        # 4. 判断是否以常见的电话码开头
        if phone_num.startswith('13') or phone_num.startswith('15') or phone_num.startswith('17')or phone_num.startswith('18') or phone_num.startswith('19'):
            print('手机号合法')
            print(int(phone_num))
        else:
            print('手机号开头不对')
    else:
        print('手机号总长度必须是11')
else:
    print('手机号必须是纯数字')

image

# 正则表达式实现
import re
phone_num = input('把你的手机号告诉我>>:').strip()
if re.match('^[13|15|17|18|19][0-9]{9}',phone_num):
    print(phone_num)
else:
    print('输入不合法')

image

2. 正则表达式之字符组

2.1 正则表达式线上测试网址:http://tool.chinaz.com/regex/

2.2 字符组在没有量词修饰的情况一次只会针对一个数据值

2.3 [0-9]

匹配0到9之间的任意一个数字(包括0和9)全称是:[0123456789]

2.4. [A-Z]

匹配A到Z之间的任意一个字母(包括A和Z)全称是:[ABC...XYZ]

2.5. [a-z]

匹配a到z之间的任意一个字母(包括a和z)全称是:[abc...xyz]

2.6. [0-9a-zA-Z]

在中括号内编写的多个数据值彼此都是或的关系, 数字,小写字母,大写字母都可以

3. 正则表达式之特殊符号

3.1 特殊符号在没有量词修饰的情况一个符号一次只会针对一个数据值

3.2 字符

元字符 匹配内容
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线
\s 匹配任意的空白符
\d 匹配数字
\n 匹配一个换行符
\t 匹配一个制表符
\b 匹配一个单词的结尾
^ 匹配字符串的开始
$ 匹配字符串的结尾
\W 匹配非字母或数字或下划线
\D 匹配非数字
\S 匹配非空白符
() 匹配括号内的表达式,也表示一个组
[...] 匹配字符组中的字符
[^...] 匹配除了字符组中字符的所有字符

4. 正则表达式之量词

4.1 在正则表达式中所有的量词默认都是贪婪匹配(尽可能多的)

4.2 量词不能单独使用,必须跟在表达式的后面,并且只能影响紧挨着的左边那一个

4.3 量词

量词 用法说明
* 重复零次或更多次
+ 重复一次或更多次
重复零次或一次
重复n次
重复n次或更多次
重复n到m次

5. 正则表达式练习

5.1 . ^ $

正则 待匹配字符 匹配结果 说明
海. 海燕海娇海东 海燕海娇海东 匹配所有"海."的字符
^海. 海燕海娇海东 海燕 只从开头匹配"海."
海.$ 海燕海娇海东 海东 只匹配结尾的"海.$"

5.2 * + ? ()

正则 待匹配字符 匹配结果 说明
李.? 李杰和李莲英和李二棍子 李杰,李莲,李二 ?表示重复零次或一次,即只匹配"李"后面一个任意字符
李.* 李杰和李莲英和李二棍子 李杰和李莲英和李二棍子 *表示重复零次或多次,即匹配"李"后面0或多个任意字符
李.+ 李杰和李莲英和李二棍子 李杰和李莲英和李二棍子 +表示重复一次或多次,即只匹配"李"后面1个或多个任意字符
李. 李杰和李莲英和李二棍子 李杰和,李莲英,李二棍

5.3 [] [^]

正则 待匹配字符 匹配结果 说明
李[杰莲英二棍子]* 李杰和李莲英和李二棍子 李杰,李莲英,李二棍子 表示匹配"李"字后面[杰莲英二棍子]的字符任意次
李[^和]* 李杰和李莲英和李二棍子 李杰,李莲英,李二棍子 表示匹配一个不是"和"的字符任意次
[\d] 456bdha3 4,5,6,3 表示匹配任意一个数字,匹配到4个结果
[\d]+ 456bdha3 456,3

6. 贪婪匹配与非贪婪匹配

6.1 贪婪匹配

待匹配的文本:<script>alert(123)</script>
正则表达式:<.*>  
上述正则匹配出来的内容是:<script>alert(123)</script>

6.2 非贪婪匹配

待匹配的文本:<script>alert(123)</script>
正则表达式:<.*?>  
上述正则匹配出来的内容是:<script>      </script>

6.3 总结

  1. 所有的量词默认都是贪婪匹配,但是如果在量词的后面紧跟一个问号那么就会变成非贪婪匹配
  2. 以后在使用贪婪匹配或者非贪婪匹配的时候一般都是用 .或者.? 并且结束的标志有符号两边添加的表达式决定

7. 取消转义

7.1 正则表达式中取消斜杠与字母的特殊含义,就是在斜杠前面加斜杠

\\n		\n
\\\\n		\\n

7.2 在python中有更加简便的写法

r'\n'
r'\\n'

8. 正则表达式实战

8.1 编写校验用户手机号的正则

0?(13|14|15|17|18|19)[0-9]{9}

8.2 编写校验用户身份证的正则

\d{17}[\d|x]|\d{15}

8.3 编写校验用户身份证的正则

\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}

8.4 编写校验用户qq号的正则

[1-9]([0-9]{5,11})

8.5 常见的正则百度查找

作业

# 查看购物车
@login_auth
def check_shop_car():
    # 1.获取用户字典
    with open(os.path.join('db', login_dict['username']), 'r', encoding='utf8') as f:
        user_dict = json.load(f)
    # 2.获取购物车字典
    shop_car = user_dict['shop_car']
    # 3.循环获取商品名和商品信息
    for good_name, good_info in shop_car.items():
        print(f"商品名称:{good_name}  |  商品数量:{good_info[0]}  |  商品单价:{good_info[1]}  |  总价:{good_info[0] * good_info[1]}")


# 修改购物车
@login_auth
def update_shop_car():
    # 1.获取用户字典
    with open(os.path.join('db', login_dict['username']), 'r', encoding='utf8') as f:
        user_dict = json.load(f)
    # 2.获取购物车字典
    shop_car = user_dict['shop_car']
    while True:
        # 3.打印商品信息
        for good_name in shop_car:
            print(f"商品名称:{good_name}  |  商品数量:{shop_car[good_name][0]}  |  商品单价:{shop_car[good_name][1]}  |  总价:{shop_car[good_name][0] * shop_car[good_name][1]}")
        # 4.获取想要修改的商品名称
        choice = input('请输入需要修改的商品名称(输入q退出)>>>:').strip()
        # 5.退出并修改购物车
        if choice == 'q':
            user_dict['shop_car'] = shop_car
            with open(os.path.join('db', login_dict['username']), 'w', encoding='utf8') as f:
                json.dump(user_dict, f, ensure_ascii=False)
            break
        if choice not in shop_car:
            print('该商品不存在')
            continue
        print("""
        1.增加该商品数量
        2.减少该商品数量
        3.移除该商品数量
        """)
        # 6.获取要进行的操作
        func_choice = input('请输入想要进行的操作编号>>>:').strip()
        # 7.操作字典
        shop_func_dict = {
            '1': add_shop_num,
            '2': reduce_shoo_num,
            '3': clear_shop_num
        }
        if func_choice in shop_func_dict:
            shop_car = shop_func_dict[func_choice](shop_car, choice)
        else:
            print('请输入正确编号')
            continue


# 增加商品
def add_shop_num(shop_car, good_name):
    num = input('请输入要添加的数量>>>:').strip()
    if not num.isdigit():
        print('请输入正确数量')
        return shop_car
    num = int(num)
    shop_car[good_name][0] += num
    return shop_car


# 减少商品
def reduce_shoo_num(shop_car, good_name):
    num = input('请输入要减少的数量>>>:').strip()
    if not num.isdigit():
        print('请输入正确数量')
        return shop_car
    num = int(num)
    if shop_car[good_name][0] < num:
        print('减少数量大于总数量')
        return shop_car
    shop_car[good_name][0] -= num
    return shop_car


# 移除商品
def clear_shop_num(shop_car, good_name):
    shop_car.pop(good_name)
    return shop_car
posted @ 2022-07-19 16:57  |相得益张|  阅读(36)  评论(0编辑  收藏  举报