python学习--正则

正则表达式

正则表达式也叫规则表达式。

1.判断手机号

iphone = input("输入一个电话号码")
if len(iphone) == 11 and iphone[0] == "1" and iphone.isdigit():
    print("是一个手机号码。")
else:
    print("不是手机号码。")

如果再加上要求是不是以13开头,那么就要对代码进行大改变。那我们能不能少改变呢。

2.正则

先给案例。

import re  # 导入正则模块
re.findall("正则规则", "要进行匹配的字符串")  # 符合规则得到数据,不符合规则返回空列表
iphone = input("输入一个电话号码")
res = re.findall(r"13\d{9}", iphone)  # 设定13开头规则,满足规则才将iphone赋值给res
print(res)

元字符

元字符

1.通配符

通配符匹配除了换行符\n之外的任意字符。

res = re.findall("1", "12378138500")
print(res)  # ['1', '1']
res = re.findall("1.", "12378138500")
# .表示通配符即所有字符
print(res)  # ['1', '1']

当我们想要匹配\n时就想要加入一个参数re.S表示整行。没有该参数时,正则会按\n进行每行匹配,有了它\n就被视为字符串了。

res = re.findall(".", "456\n465", re.S)
print(res)  # ['4', '5', '6', '\n', '4', '6', '5']

2.正则转义

将通配符转义为.

res = re.findall("\.", "135.865")
print(res)  # ['.']

3.转义符

字符大小写匹配数据相反,以\d和\D为例

3.1 \d和\D

\d表示匹配数字

res = re.findall(r"\d", "gas46541afg")
print(res)  # ['4', '6', '5', '4', '1']

\D表示匹配除了数字

res = re.findall(r"\D", "gas46541afg")
print(res)  # ['g', 'a', 's', 'a', 'f', 'g']

这里注意一点为了防止正则转义被常规转义影响如\n表示换行,我们采取在该字符串前加上r表示取消常规转义

3.2 \s

匹配空格,制表符,换行符

res = re.findall(r"\s", "gas   4  \n6541afg")
print(res)  # [' ', ' ', ' ', ' ', ' ', '\n']

3.3 \w

匹配字母,数字,下划线,汉字

res = re.findall(r"\w", "gas你好 _4  \n65g")
print(res)  # ['g', 'a', 's', '你', '好', '_', '4', '6', '5', 'g']

3.4\b

空格,此处不做演示。

4.脱字符

^用于限定开头的内容

res = re.findall(r"^13", "124861465")
print(res)  # []

5.美元符

$用于限定结尾的内容

res = re.findall(r"13$", "124861465")
print(res)  # []

同时限定开头和结尾,并且中间是数据\d

res = re.findall("^13\d65$", "134861465")
print(res)  # []
# 因为\d仅代表一个字符,所以只有当其为"13465"或类似数据才可匹配
# 而\d+可以匹配一个或多个字符
res = re.findall("^13\d+65$", "134861465")
print(res)  # ['134861465']

6.匹配次数

6.1 {}

匹配指定次数{最少次数,最多次数}{1,}表示匹配1次到多次与+相同,{9}表示匹配9次。注意,左右不能有空格。

res = re.findall(r"\d{2,3}", "gas你好 _4  \n6541afg")
print(res)  # ['654']

6.2 +

匹配一次或多次。

res = re.findall(r"\d+", "gas你好 _4  \n6541afg")
print(res)  # ['4', '6541']

6.3 *

匹配0次或多次,匹配0次代表着不符合则返回空字符串。

res = re.findall(r"\d*", "gas你好 _4  \n6541afg")
print(res)  # ['', '', '', '', '', '', '', '4', '', '', '', '6541', '', '', '', '']

6.4 ?

匹配0次或1次,匹配0次代表着不符合则返回空字符串。

res = re.findall(r"\d?", "gas你好 _4  \n6541afg")
print(res)  # ['', '', '', '', '', '', '', '4', '', '', '', '6', '5', '4', '1', '', '', '', '']

7.贪婪和非贪婪匹配

贪婪就是尽可能拿最多,非贪婪就是最少。

7.1贪婪匹配

存在回溯过程。

str1 = "<html> ejy<span>dasdas</span> jyw</html>123"
res = re.findall(r"<.*>", str1)
print(res)  # ['<html> ejy<span>dasdas</span> jyw</html>']

该代码的意思是寻找以<开头以>结尾的最大字符串,其从左匹配<,从右匹配>。

7.1非贪婪匹配

要求在控制匹配次数的字符后加上?

str1 = "<html> ejy<span>dasdas</span> jyw</html>123"
res = re.findall(r"<.*?>", str1)
print(res)  # ['<html>', '<span>', '</span>', '</html>']

8.集合匹配

[0-9]表示匹配0至9闭区间的单个数字在这里脱字符^表示取反。

str1 = "gas你好 _4  \n6541afg"
res = re.findall(r"[0-9]", str1)
print(res)  # ['4', '6', '5', '4', '1']
str1 = "gas你好 _04  \n06541219afg"
res = re.findall(r"[0-12]", str1)  # 单个数字
print(res)  # ['0', '0', '1', '2', '1']
str1 = "gas你好 _04  \n06541219afg"
res = re.findall(r"[012]", str1)  # 没有-表示0或1或2
print(res)  # ['0', '0', '1', '2', '1']
str1 = "gas你好 _04  \n06541219afg"
res = re.findall(r"[^0-5]", str1)
print(res)  # ['g', 'a', 's', '你', '好', ' ', '_', ' ', ' ', '\n', '6', '9', 'a', 'f', 'g']

9.分组匹配

只拿小括号里的内容

str1 = "this is python "
res = re.findall(r"(is)", str1)
print(res)  # ['is', 'is']
res = re.findall(r"is", str1)
print(res)  # ['is', 'is']

有同学会觉得这个括号没有用,那我们看看下面的例子。

str1 = "this is python "
res = re.findall(r"i(s)", str1)
print(res)  # ['s', 's']

这下应该明白了吧。
当我们想要保留括号外面的内容时,有同学感觉既然要保留为何不括在一起呢?因为括号也表示一个整体,有些数据就要分开括起来,这时都要保留的话就需要了。

str1 = "this is python "
res = re.findall(r"i(?:s)", str1)  # 保留括号外面的
print(res)  # ['is', 'is']
res = re.findall(r"i(?=s)", str1)  # 只保留括号外面的
print(res)  # ['i', 'i']
res = re.findall(r"i(?!s)", str1)  # 返回与括号内不匹配的括号外的内容
print(res)  # ['i', 'i']

re模块

1.compile方法

该方法使语句提前编译,可以在后面随时调用。这样子就可以像函数那样将规则封装至一起。

str1 = "<html> ejy<span>dasdas</span> jyw</html>123"
str2 = "gas你好 _4  \n6541afg"
r = re.compile(r'\d')
res1 = r.findall(str1)
res2 = r.findall(str2)
print(res1)  # ['1', '2', '3']
print(res2)  # ['4', '6', '5', '4', '1']

2.sub方法

该方法实现字符串替换。

res = re.sub("12", "hello", "12, ice")
print(res)  # hello, ice
res = re.sub("12", "hello", "12, ice,121212", 2)  # 也可以指定替换次数
print(res)  # hello, ice,hello1212

3.split方法

与字符串里的split类似。

res = re.split("[,| ]", "hello pyth,on")  # 其中|表示或
print(res)  # ['hello', 'pyth', 'on']

4.match方法

该方法可以查找但是要求必须在第一个。

res = re.match(r'1', "1hell1o pyt1h,o11n")
print(res)  # <re.Match object; span=(0, 1), match='1'>

(0, 1)表示索引

5.search方法

仅查找一次,但不限于开头。

res = re.search(r'1', "hell1o pyt1h,o11n")
print(res)  # <re.Match object; span=(4, 5), match='1'>

上次练习答案

# 1.利用装饰器,记录函数的运行日志(如:保存传入参数,返回结果,运行时间等信息)
import time as t


def message(*args0):
    def fun1(f):
        argument = open("../file/argument.txt", "a+")
        re = open("../file/return.txt", "a+")
        time = open("../file/time.txt", "a+")

        def fun(*args):
            start = t.time()
            a = f(*args)
            end = t.time()
            run = end - start
            argument.write(str(args))
            argument.write("\n")
            re.write(str(a))
            re.write("\n")
            time.write(str(run))
            time.write("\n")

        return fun

    @fun1
    def test_fun(*args0):
        print(args0)
        return args0

    test_fun(*args0)


message(1, 2, 5, 3, 85, 4)
# 2.打开一个只读文件,如果文件不存在,则去创建这个文件
def test02():
    try:
        a = open("../file/aaa.txt", "r")
    except FileNotFoundError:
        print("找不到该文件")
        b = open("../file/aaa.txt", "w")
        b.close()
    finally:
        a = open("../file/aaa.txt", "r")
        # a.read()
        return a


test02()

练习

  1. 检查用户名是否是由字母数字下划线中文组成。
  2. 检查邮箱是否符合规范(邮箱开头可以是字母或数字,但不超过16位,中间必须有@,@后字母或数字限制6位或以内但必须有,接下来必须要有.com。
  3. 检查用户的身份证号码是否符合规范,第一个数字(0-8)年份要求(1900-2022)月份不能超过12,日期只要求(01-31),结尾3个数字一个x或4个数字。

结束语

点赞!!!
ps:现在关注我,以后就是老粉啦!!!

下篇预告

python基础学习结束啦,接下来是linux系统学习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值