Day10 Python系统模块

文章目录

    • 第七章 Python系统模块
      • 7.1. 模块和包
        • 7.1.1. 模块
        • 7.1.2. 第三方模块下载
          • 7.1.2.1. 替换国内源
          • 7.1.2.2. pip常用命令
          • 7.1.2.3. 模块之间的互相调用
        • 7.1.3. 包
      • 7.2. 可迭代类型
        • 7.2.1. 可迭代对象与迭代器对象
        • 7.2.2. 自定义迭代器
          • 7.2.2.1. 自定义迭代器遍历其他序列
        • 7.2.3. 生成器
          • 简单表达式
          • 函数生成器
          • 生成器特点
      • 7.3. 时间模块
        • 7.3.1. time
        • 7.3.2. datetime
        • 7.3.3. calendar模块
      • 7.4. 数学模块
      • 7.5. 随机数模块
      • 7.6. 字符串模块
      • 7.7. hashlib加密模块
      • 7.8. base64模块
      • 7.9. collections模块
      • 7.10. 正则模块
        • 7.10.1. 正则的介绍
        • 7.10.2. 常用元字符
        • 7.10.3. Python的正则基本处理
        • 7.10.4. 示例代码

第七章 Python系统模块

7.1. 模块和包

7.1.1. 模块

所谓的“模块”,其实就是指的py文件!模块之间是可以互相调用的!

在Python中,模块分为三种:

  • 系统模块:Python环境安装完成之后自带的py文件或者包
  • 自定义模块:就是我们自己写的py文件
  • 第三方模块:其他人写好的,上传到 pypi.org 上面,可以下载下来使用的模块

7.1.2. 第三方模块下载

下载第三方模块最简单的方式,就是使用 pip 工具来下载。我们在安装Python环境的时候,pip命令已经安装完成了。

在Windows平台上,python解释器的命令就是python,pip工具的命令就是pip。

在mac平台上,python解释器的命令就是python3,pip工具的命令就是pip3。

7.1.2.1. 替换国内源

pip可以去搜索和下载仓库中的第三方的模块,但是这些仓库在远端,使用到的是国外的镜像仓库,有些第三方模块在下载的时候可能会比较慢。因此在实际的使用中,我们经常会将镜像源替换成国内的源。

常见的国内的镜像有:

阿里云:http://mirrors.aliyun.com/pypi/simple/

清华大学:https://pypi.tuna.tsinghua.edu.cn/simple/

中国科学技术大学:http://pypi.mirrors.ustc.edu.cn/simple/

百度:https://mirror.baidu.com/pypi

豆瓣:http://pypi.douban.com/simple/

如果我们在下载第三方模块的时候,临时指定使用指定的源进行下载,可以这样做:

# 指定阿里云的源,下载PyMySQL
pip install -i http://mirrors.aliyun.com/pypi/simple PyMySQL

但是每一次都这样去指定源下载,会非常的麻烦。那么能不能一劳永逸的解决问题?此时我们可以修改配置文件来达到这个效果。

  • Windows:
    • 需要修改的文件是:C:\Users\{当前用户}\AppData\Roaming\pip\pip.ini,如果没有这个文件,就手动创建一下。
  • macOS、Linux:
    • 需要修改的文件是:~/.pip/pip.info

写入如下内容,并保存

[global]
	index-url=http://mirrors.aliyun.com/pypi/simple
	trusted-host=mirrors.aliyun.com
7.1.2.2. pip常用命令
# 查看版本
pip --version

# 安装指定的包
pip install PyMySQL				# 安装PyMySQL的最新版本
pip install PyMySQL==1.0.4		# 安装PyMySQL的指定版本

# 升级包
pip install --upgrade PyMySQL	# 升级PyMySQL,也可以使用==指定版本号

# 卸载包
pip uninstall PyMySQL			# 卸载PyMySQL

# 列出已经安装的包
pip list

# 显示安装包的信息
pip show PyMySQL

# 查看指定安装包的详细信息
pip show -f PyMySQL
7.1.2.3. 模块之间的互相调用

模块之间是可以互相调用的,在使用之前要先引入指定的模块。引入的语法有三种:

python"># 1. 使用模块中的内容的时候,需要使用 模块名.内容
import 模块名

# 2. 使用内容的时候,直接操作即可
from 模块名 import 内容1, 内容2

# 3. 引入模块中的所有内容,需要注意的是如果模块下使用了 __all__规定了对外够哦那个开的内容,那么只能够引入这些内容
from 模块名 import *
python"># my.py
__all__ = ['test_method']
class NumberTool:
    @staticmethod
    def add(*args):
        s = 0
        for n in args:
            s += n
        return s


def test_method():
    print("test_method")
    

# use1.py
import my
print(my.NumberTool.add(10, 20, 30))		# 需要使用 模块.内容 的方式来访问
print(my.test_method())


# use2.py
from my import NumberTool
print(NumberTool.add(10, 20, 30))			# 可以直接使用内容来访问
# test_method()								# 这个函数是访问不到的


# use3.py
from my import *
test_method()								# 直接访问,但是只能访问到 __all__ 中定义的部分

7.1.3. 包

一个py文件就是一个模块,那么将多个具有相关联的功能的模块组织到一起,就是一个。其实包和目录的功能类似,都可以将若干个功能相似的模块组织到一起,我们在使用到这些模块的时候,就可以直接通过这样的目录结构,找到对应的模块来使用。

包和文件夹的区别,目前也就是包下会有一个 _init_.py 的文件了。

可以理解为,包含 _init_.py 的文件夹就是包,不包含的就是普通的文件夹。

在Python2的版本中,没有_init_.py的时候,是无法导入这个包下的模块中的内容的。

但是Python3中已经不限制了,有没有_init_.py都可以正常导入包下的模块中的内容。

那么,这个_init_.py文件是干嘛的?

其实现在就只有一个预加载的作用了。我们在导入一个包的时候,会先执行这个包下的_init_.py文件中的代码。因此我们就可以在这个文件中进行一些预处理操作。

7.2. 可迭代类型

7.2.1. 可迭代对象与迭代器对象

collections包下的abc模块中,有一个Iterable,表示可迭代类型。可迭代类型即可以依次获取到每一个元素,可以使用for-in遍历。

python">from collections.abc import Iterable

print(isinstance(10, Iterable))  # False
print(isinstance('abc', Iterable))  # True
print(isinstance([], Iterable))  # True
print(isinstance(map(str, [10, 20, 30]), Iterable))  # True

在遍历可迭代类型的时候,有些是使用别的序列在记录遍历位置,有些则是自己在记录遍历位置。那么,记录着迭代位置的对象,就是一个“迭代器”。

python">from collections.abc import Iterator

print(isinstance(10, Iterator))  # False
print(isinstance('abc', Iterator))  # False
print(isinstance([], Iterator))  # False
print(isinstance(map(str, [10, 20, 30]), Iterator))  # True
python">'''
迭代器序列的数据的特点:
	取值只能向前 不能向后  取出之后 迭代器中就没有这个数据了
除了可以使用for-in进行遍历之外 还可以使用next(序列)获取序列中的元素
'''
s = 'hello'
for ch in s:
	print(ch)

print('===')

for ch in s:
	print(ch)
print('===')
'''
可迭代类型 非迭代器序列类型的数据 在遍历的时候 先创建一个迭代器对象 用它来记录位置 逐个获取元素
'''

# 迭代器序列类型的数据 先把自身设置迭代器【记录自身位置】 然后逐个取值
seq = map(str, [10, 20, 30])
for ele in seq:
	print(ele)
print('====')
for ele in seq:
	print(ele)

7.2.2. 自定义迭代器

在一个类中定义了 _iter_ 魔术方法的,就可以称为是可迭代对象了。这个方法需要返回一个迭代器对象,可以是自己,也可以是其他对象。

在一个类中同时定义了 _iter_ 和 __next__ 魔术方法的,就可以称为是迭代器对象了。

在使用for-in遍历可迭代对象的时候,其实是先获取到迭代器对象,然后每一次循环都调用__next__方法,获取到下一个元素。

python">class Fibonacci:
    def __init__(self, bound):
        self.bound = bound      # 记录边界
        # 记录从几开始遍历
        self.current = 1
        # 记录前两位的数字
        self.number_1 = 1
        self.number_2 = 1
        # 记录当前的数字
        self.current_number = 1

    def __iter__(self):
        return self

    def __next__(self):
        if self.current <= self.bound:
            if self.current > 2:
                self.current_number = self.number_1 + self.number_2
                # 为下一位做准备
                self.number_1 = self.number_2
                self.number_2 = self.current_number
            # 位数+1
            self.current += 1
            return self.current_number
        else:
            # raise ValueError("后面没有了")
            raise StopIteration


fib = Fibonacci(10)

for ele in fib:
    print(ele)

for ele in fib:
    print(ele)

print(isinstance(fib, Iterable))
print(isinstance(fib, Iterator))
7.2.2.1. 自定义迭代器遍历其他序列
python">class MySequenceIterator:
    def __init__(self, seq):
        self.seq = seq      # 记录需要遍历的序列
        self.current = 0    # 记录当前遍历到的位置

    def __iter__(self):
        return self         # 以自己作为迭代器

    def __next__(self):
        if self.current < len(self.seq):
            # 获取到指定位的元素
            value = self.seq[self.current]
            # 迭代位置自增
            self.current += 1
            # 返回处理之后的数据
            return str(value).title()
        else:
            raise StopIteration


# 创建一个序列
l = ["hello world", "python language", "hadoop distributed file system", "mysql database"]
for e in MySequenceIterator(l):
    print(e)

7.2.3. 生成器

生成器是一种特殊的迭代器,支持迭代器的所有的操作。使用生成器主要用来生成一个序列的。

生成器分为两种:

  • 简单表达式:类似于列表推导式
  • 函数生成器:定义一个函数,用来生成一系列的数据,将return换成yield即可
简单表达式
python"># 列表推导式,直接生成一个列表
l1 = [f"{x:03d}" for x in range(1, 200) if x % 7 == 0 and x % 3 == 0]
print(l1)

# 简单表达式生成器,获取到一个生成器对象
l2 = (f"{x:03d}" for x in range(1, 200) if x % 7 == 0 and x % 3 == 0)
print(l2)       # <generator object <genexpr> at 0x10474b780>

print(next(l2)) # 021
print(next(l2)) # 042
函数生成器
python">def get_generator():
    for i in range(5, 10000, 5):
        if i % 3 == 0:
            yield i

"""
return: 结束函数,并把结果返回到调用的位置
yield: 根据逻辑,将数据产出并暂停生产。当下一次获取数据的时候,继续生产数据
"""
gen = get_generator()

print(next(gen))
print(next(gen))
生成器特点

生成器并不直接生成全部的数据,而是根据数据生成的逻辑,每次调用next的时候,才会生成一个元素

因此,生成器常用于在程序中使用大量的数据的时候,此时会有明显的内存占用的效果

7.3. 时间模块

7.3.1. time

python">import time

# 1. 获取当前时间对应的时间元组
time_tuple = time.localtime()
print(time_tuple)
# time.struct_time(tm_year=2022, tm_mon=8, tm_mday=30, tm_hour=14, tm_min=43, tm_sec=15, tm_wday=1, tm_yday=242, tm_isdst=0)
# 年
year = time_tuple[0]
print(year)
# 还可以根据类属性名获取相关的信息
month = time_tuple.tm_mon
print(month)  # 8

# 2. 获取当前时间对应的时间戳 [应该是个整型 Python设计成了浮点型]
timestamp = time.time()  # 从当前时间到1970年1月1日经历的秒数
print(timestamp)  # 1661842192.4782896
print(int(timestamp))  # 1661842192


# 3. 时间格式化 【按照指定的格式把时间显式出来】 --- 结果是字符串
# time.strftime('展示的时间格式', 时间元组)
'''
时间格式的展示不是随便写的 是需要用指定的时间代表占位符来设置格式的
'''
print(time.strftime('%Y/%m/%d %H:%M:%S', time_tuple))  # 2022/08/30 14:57:47
print(time.strftime('%Y/%m/%d %p %I:%M:%S', time_tuple))  # 2022/08/30 PM 02:58:12
print(time.strftime('%Y/%m/%d %p %I:%M:%S %w %j', time_tuple))  # 2022/08/30 PM 02:58:49 2 242
# w 星期   j是一年中的第几天

# 4. 时间反格式化  ----> 时间元组
# time.strptime(特定格式的字符串显式的时间, '解析字符串格式时间的占位模板')
'''
字符串格式的时间 要和  解析模板要对应好
'''
new_time = time.strptime('2022-08-20 19:22:37', '%Y-%m-%d %H:%M:%S')
print(new_time)
# time.struct_time(tm_year=2022, tm_mon=8, tm_mday=20, tm_hour=19, tm_min=22, tm_sec=37, tm_wday=5, tm_yday=232, tm_isdst=-1)


# 5.获取时间元组对应的时间戳
print(time.mktime(new_time))  # 1660994557.0

# 6. 将时间戳 转化为时间元组
print(time.localtime(1660994000))
# time.struct_time(tm_year=2022, tm_mon=8, tm_mday=20, tm_hour=19, tm_min=13, tm_sec=20, tm_wday=5, tm_yday=232, tm_isdst=0)

# 7. 时间休眠
time.sleep(10)
print('睡醒了')

7.3.2. datetime

python">import datetime

# datetime.date
# datetime.datetime
# datetime.time
# datetime.timedelta

# 1.构造时间
date = datetime.date(2022, 8, 20)
print(date, type(date))  # 2022-08-20 <class 'datetime.date'>

datetime0 = datetime.datetime(2022, 8, 13)
print(datetime0, type(datetime0))  # 2022-08-13 00:00:00 <class 'datetime.datetime'>

time = datetime.time(17, 22, 34)
print(time, type(time))  # 17:22:34 <class 'datetime.time'>

# 2. 获取当前时间
cur_datetime = datetime.datetime.now()
print(cur_datetime, type(cur_datetime))  # 2022-08-30 15:41:00.270011 <class 'datetime.datetime'>

# 3. 获取datetime date日期
print(cur_datetime.date())  # 2022-08-30
print(cur_datetime.year)  # 2022
print(cur_datetime.month, cur_datetime.day, cur_datetime.hour, cur_datetime.minute, cur_datetime.second)
print(cur_datetime.weekday())  # 星期


# 4. 对时间进行格式化
'时间对象.strftime(格式化模板)'
print(cur_datetime.strftime('%Y/%m/%d %p %I:%M:%S'))  # 2022/08/30 PM 03:44:24

# 5. 时间反格式化
'''
类方法
datetime.datetime.strptime(字符串格式的时间, 反格式化模板)
'''
dt = datetime.datetime.strptime('2020-11-30 22:37:45', '%Y-%m-%d %H:%M:%S')
print(dt, type(dt))  # 2020-11-30 22:37:45 <class 'datetime.datetime'>

# 6. 获取时间戳
# 时间对象.timestamp()
print(cur_datetime.timestamp())  # 1661845623.276597

# 7. 时间戳转时间
# 类方法
print(datetime.datetime.fromtimestamp(1661844000))  # 2022-08-30 15:20:00

# 8. 时间差
d1 = datetime.datetime(2022, 7, 31)
d2 = datetime.datetime(2022, 5, 16, 17, 56, 24)
time_diff = d1 - d2
print(time_diff, type(time_diff))  # 75 days, 6:03:36 <class 'datetime.timedelta'>
# 只获取差的天数
print(time_diff.days)  # 75
print(f'减去天数之外 剩余时间对应的秒数 {time_diff.seconds}')  # 减去天数之外 剩余时间对应的秒数 21816
print(f'包含天数在内的时间全部转化为秒数 {time_diff.total_seconds()}') # 包含天数在内的时间全部转化为秒数 6501816.0

now = datetime.datetime.now()
print(now)
# 三天后的时间
print(now + datetime.timedelta(days=3))

# 一星期前的时间
print(now - datetime.timedelta(weeks=1))

7.3.3. calendar模块

python">import calendar

print(calendar.calendar(2022))  # 这一年的日历

print(calendar.month(2022, 8))  # 某一年 某个月的日历

print(calendar.isleap(2020))  # True  判断年是否为闰年
print(calendar.leapdays(1990, 2020))  # 7  闰年的个数

7.4. 数学模块

python">import math

print(f'取绝对值 {math.fabs(-234)}')  # 取绝对值 234.0
print(f'求指定数的幂数 {math.pow(2, 4)}')  # 求指定数的幂数 16.0
print(f'无精度损失的求和 {math.fsum([0.1] * 10)}')  # 无精度损失的求和 1.0
print(f'可能会存在精度损失的求和 {sum([0.1] * 10)}')  # 可能会存在精度损失的求和 0.9999999999999999
print(f'向上取整【大于或者等于数据 且最接近于数据的整数】 {math.ceil(19.5)}')  # 向上取整【大于或者等于数据 且最接近于数据的整数】 20
print(f'向上取整【大于或者等于数据 且最接近于数据的整数】 {math.ceil(-19.5)}')  # 向上取整【大于或者等于数据 且最接近于数据的整数】 -19
print(f'向上取整【大于或者等于数据 且最接近于数据的整数】 {math.ceil(19.1)}')  # 向上取整【大于或者等于数据 且最接近于数据的整数】 20
print(f'向下取整【小于或者等于数据 且最接近于数据的整数】 {math.floor(19.0)}')  # 向下取整【小于或者等于数据 且最接近于数据的整数】 19
print(f'向下取整【小于或者等于数据 且最接近于数据的整数】 {math.floor(19.9)}')  # 向下取整【小于或者等于数据 且最接近于数据的整数】 19
print(f'阶乘 {math.factorial(5)}')  # 阶乘 120
print(f'对数函数 {math.log2(32)}')  # 对数函数 5.0
print(f'圆周率 {math.pi}')  # 圆周率 3.141592653589793
print(f'三角函数 {math.sin(math.pi/6)}')  # 三角函数 0.49999999999999994
print(f'三角函数 {math.tan(math.pi/4)}')  # 三角函数 0.9999999999999999

print(f'角度转化为弧度 {math.radians(90)}')  # 角度转化为弧度 1.5707963267948966
print(f'弧度转换为角度 {math.degrees(math.pi/3)}')  # 弧度转换为角度 59.99999999999999

7.5. 随机数模块

python">import random

# 在指定的序列中随机选择一个元素
ele = random.choice('qwertyuiopasdfghjklzxcvbnm')
print(ele)
ele = random.choice(range(3, 100, 10))
print(ele)

# 在指定的序列中随机选择指定个数的元素  [选择出来的可能会重复]
eles = random.choices('qwertyuiopasdfghjklzxcvbnm', k=5)
print(eles)

# vlaues = []
# for i in range(5):
# 	ele = random.choice('qwertyuiopasdfghjklzxcvbnm')
# 	vlaues.append(ele)

# 在指定的序列中随机选择指定个数的元素  [选择出来的不会重复]
eles = random.sample('qwertyuiopasdfghjklzxcvbnm', k=5)
print(eles)

# 作业 【自己写逻辑 定义一个函数  在指定序列中选择不重复的指定个数的数据】

# 在指定的范围中随机选择一个整数 [唯一一个前闭后闭]
print(random.randint(10, 30))

# 在[0, 1)中随机选择一个小数
print(random.random())

# random.randrange() ===>  random.choice(range())

nums = [12, 34, 56, 82, 19, 30]
# 随机的打乱列表中的元素
random.shuffle(nums)
print(nums)

# 设置随机种子
'''
随机算法 --- 起始数据源 一般是当前时间
当没有范围  产生的随机数肯定是不一样
数据存在范围 产生的结果可能会重复

当数据起源值是一样的  产生的结果就是一样的
'''
print(random.randint(1, 100000))
random.seed(10)
print(random.randint(1, 100000))
# random.seed(10)
print(random.randint(1, 100000))

print(random.random())

7.6. 字符串模块

python">import string
'''
whitespace = ' \t\n\r\v\f'
ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz'
ascii_uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
ascii_letters = ascii_lowercase + ascii_uppercase
digits = '0123456789'
hexdigits = digits + 'abcdef' + 'ABCDEF'
octdigits = '01234567'
punctuation = r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"""
printable = digits + ascii_letters + punctuation + whitespace
'''
print(string.ascii_letters)
print(string.whitespace)

7.7. hashlib加密模块

python">import hashlib

# md5 16字节 128位  【16个单字节的符号】

# 1. 获取md5加密操作
md5 = hashlib.md5()
md5.update('1abcde56721A@1234'.encode('utf-8'))
# 获取加密摘要
print(md5.hexdigest())  # fcea920f7412b5da7be0cf42b8c93759

md5 = hashlib.md5()
md5.update('1234'.encode('utf-8'))
md5.update('567'.encode('utf-8'))
# 获取加密摘要
print(md5.hexdigest())  # fcea920f7412b5da7be0cf42b8c93759

# sha家族
sha1 = hashlib.sha1()
sha1.update('1234567890'.encode('utf-8'))
print(sha1.hexdigest())

sha256 = hashlib.sha256()
sha256.update('1234567890'.encode('utf-8'))
print(sha256.hexdigest())  # c775e7b757ede630cd0aa1113bd102661ab38829ca52a6422ab782862f268646

7.8. base64模块

python"># base64: 是目前网络上最常见的用于传输字节序列的编码方式

import base64

# 编码
b64_data = base64.b64encode('hell world'.encode('utf8'))
print(b64_data)

# 解码
print(base64.b64decode('aGVsbCB3b3JsZA==').decode('utf8'))

7.9. collections模块

python">from collections import defaultdict, Counter, deque, namedtuple

d0 = {'a': 97, 'b': 98}
# print(d0['c'])
# print(d0.get('c'))
# def get_value():
# 	return 0

# 给不存在的键设置默认值 可以使用defaultdict
d1 = defaultdict(lambda : 0)
d1.update(d0)
print(d1)
print(d1['c'])  # 0


# Counter 也是字典的一个子类
# 专门来做词频统计的  统计序列中每个元素出现的次数
s = 'aaabbbc333cccbdddaaaa333'
count_dict = Counter(s)
print(count_dict)
# Counter({'a': 7, '3': 6, 'b': 4, 'c': 4, 'd': 3})

print(count_dict.most_common(3))  # 提起排名前几的内容信息


# deque 队列
'''
队列分为单向和双向队列
	单向队列 规则是先进先出
deque 是双向队列
'''
queue = deque()
queue.append(10)
queue.append(12)
print(queue)
queue.appendleft(19)
queue.appendleft(21)
print(queue)

queue.pop()
print(queue)
queue.popleft()
print(queue)

# namedtuple 根据类型和属性名构造一个类  既有面向对象的特性 又有元组的特性  [元组的子类]
Point = namedtuple('Point', ('x', 'y'))
p = Point(18, 22)
print(p)  # Point(x=18, y=22)

# 取属性可以通过下标  也可以通过属性名
x = p[0]
print(x)

y = p.y
print(y)

7.10. 正则模块

7.10.1. 正则的介绍

正则表达式,并不是Python独有的,而是一套独立的、自成体系的知识点。在很多语言中,都有对正则的使用。

正则表达式是用来做字符串的校验、匹配的工作的,其实正则表达式只有一个作用:验证一个字符串是否与指定的规则匹配。

但是,在很多的语言中,都在匹配的基础上,添加了其他的功能。

python">"""
需求:验证一个字符串,是否是一个合法的QQ号码
    1、一个QQ号码由6到12位的数字组成,不能包含其他部分
    2、一个QQ号码不能以数字0作为开头
"""


def check_qq_number(number):
    s = str(number)
    # 验证长度
    if not 6 <= len(s) <= 12:
        return False
    # 验证纯数字
    if not s.isdigit():
        return False
    # 验证不以0开头
    if s.startswith('0'):
        return False
    return True


def check_qq_number_with_re(number):
    return re.compile('[1-9]\\d{5,11}').fullmatch(number) is not None


print(check_qq_number_with_re('012345678'))

7.10.2. 常用元字符

元字符意义
^匹配一个字符串的开头。 在fullmatch的正则匹配中,可以省略不写。
$匹配一个字符串的结尾。 在fullmatch的正则匹配中,可以省略不写。
[]匹配一位字符。
[abc]: 表示这一位的字符, 可以是a、也可以是b、也可以是c 。
[a-z]: 表示这一位的字符, 可以是 [a, z] 范围内的任意的字符。
[a-zABC]: 表示这一位的字符, 可以是 [a,z ] 范围内的任意字符, 或者A、或者B、或者C 。
[a-zA-Z]: 表示这一位的字符, 可以是任意的字母, 包括大写字母和小写字母。
[^abc]: 表示这一位的字符, 可以是除了 a、b、c 之外的任意字符。
\转义字符。
\d匹配所有的数字, 等同于 [0-9] 。
\D匹配所有的非数字, 等同于 [^0-9] 。
\w匹配所有的单词字符, 等同于 [a-zA-Z0-9_] 。
\W匹配所有的非单词字符, 等同于 [^a-zA-Z0-9_] 。
.通配符, 可以匹配一个任意的字符。
+前面的一位或者一组字符, 连续出现了一次或多次。
?前面的一位或者一组字符, 连续出现了一次或零次。
*前面的一位或者一组字符, 连续出现了零次、一次或多次。
{}对前面的一位或者一组字符出现次数的精准匹配。
{m} : 表示前面的一位或者一组字符连续出现了m次。
{m,} : 表示前面的一位或者一组字符连续出现了至少m次。
{m,n} : 表示前面的一位或者一组字符连续出现了至少m次,最多n次。
|作用于整体或者是一个分组, 表示匹配的内容, 可以是任意的一个部分。
abc|123|opq : 表示整体的部分, 可以是 abc, 也可以是 123, 也可以是 opq
()分组。 把某些连续的字符视为一个整体对待。

7.10.3. Python的正则基本处理

Python中的正则表达式基本使用
pattern_obj = re.compile(正则语法规则, 匹配的标记格式)

涉及到的几个类
re.Pattern: 正则表达式对象,用来描述正则表达式
re.Match: 匹配结果对象,用来描述正则匹配的结果,包含匹配的位置和匹配的内容
.group(): 获取到匹配的内容
.group(N): 获取匹配到的第N组的内容
.group(group_name): 获取匹配到的指定组名的内容
.span(): 获取到匹配的位置

常用方法

python">pattern_obj.match('字符串')      从前往后查找匹配项,找到了就返回匹配的部分(Match对象),找不到返回None
pattern_obj.fullmatch('字符串')  用指定的正则语法规则,匹配整个的字符串,能够匹配就返回匹配部分(Match对象),匹配不到就返回None
pattern_obj.search('字符串')     在指定的字符串中查找满足规则的子串,返回第一个匹配部分(Match对象),找不到就返回None
pattern_obj.findall('字符串')    在指定的字符串中查找所有满足规则的子串,返回一个列表
pattern_obj.finditer('字符串')   在指定的字符串中查找所有的匹配项,返回迭代器(迭代Match对象)
pattern_obj.split('字符串')      将一个字符串使用指定的正则切割
pattern_obj.sub(替换函数,字符串,替换数量)        将匹配到的每一个部分,使用指定函数处理,并替换掉原有的内容

re包简化

在re包的_init_.py文件中定义了若干个函数,用来简化上述方法的使用。

python">re.match('正则表达式', '字符串')
re.match('正则表达式', '字符串')      
re.fullmatch('正则表达式', '字符串')  
re.search('正则表达式', '字符串')     
re.findall('正则表达式', '字符串')    
re.finditer('正则表达式', '字符串')   
re.split('正则表达式', '字符串')      
re.sub('正则表达式', '替换函数''字符串''替换数量') 

匹配标记格式
re.I 忽略大小写的匹配
re.M 多行匹配,会影响到^和$
re.S 使.可以匹配包括换行符在内的所有字符

7.10.4. 示例代码

python">import re


"""
1、基础元字符匹配
"""
res1 = re.fullmatch('<div>.+</div>', '<div><p>hello</p></div>')
if res1 is not None:
    print(res1.group(), res1.span())


"""
2、分组的匹配
"""
res2 = re.fullmatch('(\\w{6,16})@(?P<company_name>126|163|qq|gmail|yahoo)\\.com', 'test_youxiang@163.com')
if res2 is not None:
    print(res2.groups())                # 获取到所有分组
    print(res2.group(1))                # 按照序号获取分组
    print(res2.group('company_name'))   # 按照名字获取分组


"""
3、按照正则切割
"""
res3 = re.split('\\d+', 'hello123world4python456mysql')
print(res3)     # ['hello', 'world', 'python', 'mysql']


"""
4、按照正则替换
"""
res4 = re.sub('\\d+', ', ', 'tom123jerry33lilei45lucy')
print(res4)     # tom, jerry, lilei, lucy

http://www.niftyadmin.cn/n/473948.html

相关文章

Git 常用指令

查看修改的文件 将修改的文件添加到版本库 Git如何创建、切换、删除分支? 合并分支 新建分支 切换分支 合并分支&#xff0c;解决冲突 删除分支

python的格式化输出

print中的占位符(%-fomatting) print中的%d,%s等&#xff0c;只是一个占位符&#xff0c;等正确内容到了再查进去。 注意&#xff1a;变量值和打印内容之间不能有逗号隔开。 使用fomat方法 format底层可以理解成一个字典&#xff0c;默认key是按顺序从0开始&#xff0c;指定key…

SpringBoot 最新版3.x 集成 OAuth 2.0 实现认证授权服务、第三方应用客户端以及资源服务

前言 Spring Boot 3已经发布一段时间&#xff0c;网上关于Spring Boot 3的资料不是很多&#xff0c;本着对新技术的热情&#xff0c;学习和研究了大量Spring Boot 3新功能和新特性&#xff0c;感兴趣的同学可以参考Spring官方资料全面详细的新功能/新改进介绍 Spring版本升级到…

Webpack和Vite简单使用

目录 WebPack 介绍 基础使用 初始化使用 webpack.config.js文件 webpack开发服务器 vite 介绍 使用 使用vite创建vue框架项目 WebPack 介绍 当我们习惯了在node中编写代码的方式后&#xff0c;在回到前端编写html、css、js这些东西会感觉到各种的不便。比如: 不能放心…

【UE Cesium】01-在虚幻5中使用Cesium

UE版本&#xff1a;5.1 步骤 1. 首先我们新建一个空白的工程 2. 在虚幻商城中搜索“Cesium for Unreal”&#xff0c;然后点击“安装到引擎” 3. 在虚幻编辑器中搜索插件“cesium”&#xff0c;勾选如下插件&#xff0c;然后重启编辑器 4. 重启后我们新建一个空白关卡 保存关卡…

【Vue3】CustomImport 导入文件组件

1. 效果图 2. 组件完整代码 <template><div class"custom-import-warpper"><el-dialog v-model"dialogVisible" :title"dialogTitle" width"600px" :close-on-click-modal"false"><el-form label-wid…

SQL count(1)、count(*) 与 count(列名) 到底有什么区别?

count(*) 和 count(1)和count(列名)区别 执行效果上&#xff1a; count(*)包括了所有的列&#xff0c;相当于行数&#xff0c;在统计结果的时候&#xff0c;不会忽略为NULL的值。 count(1)包括了忽略所有列&#xff0c;用1代表代码行&#xff0c;在统计结果的时候&#xff0c…

《Pytorch深度学习和图神经网络(卷 1)》学习笔记——第五章

全连接神经网络 隐藏层的节点数决定了模型拟合能力&#xff0c;如果在单隐藏层设置足够多的节点&#xff0c;理论上可以拟合世界上各种维度的数据进行任意规则的分类&#xff0c;但会过拟合。 隐藏层的数量决定了其泛化能力&#xff0c;层数越多&#xff0c;推理的能力越强&am…