Python的模块、包和库

  • 模块(Module)通常以.py为扩展名,可以被其他程序通过import语句导入使用。
  • 包(Package)包含多个模块,必须包含一个特殊的__init__.py文件,这个文件可以为空,但它的存在表明这个目录可以被作为一个包来使用。
  • 库(Library)是一组完成特定功能的模块或包的集合,第三方库是Python强大生态系统的重要组成部分,它们提供了各种各样的工具和框架,使得Python成为一个功能丰富的编程语言。

re模块

  • 使用 re 模块来处理正则表达式,正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。

简单的正则

  1. .:匹配除换行符 外的任意一个字符。
  2. ^:匹配字符串的开头。
  3. $:匹配字符串的结尾。
  4. *:匹配前一个字符的0次或多次重复。
  5. +:匹配前一个字符的1次或多次重复。
  6. ?:匹配前一个字符的0次或1次重复。
  7. {}:指定匹配次数的范围。
  8. []:匹配方括号内的任意一个字符。注意:^放在[]内部时表示取反。
  9. :转义字符,用于匹配特殊字符本身。
  10. |:逻辑或,匹配两个模式中的任意一个。
  11. ():分组,用于限定匹配范围或指定优先级。

字符类正则

  1. 匹配任何十进制数字,等价于字符类 [0-9] 。
  2. :匹配任何非数字字符,等价于字符类 [^0-9] 。
  3. :匹配任何空白字符(空格),等价于字符类 [ 。
  4. :匹配任何非空白字符(不是空格),等价于字符类 [^ 。
  5. :匹配任何字母、数字、下划线字符,等价于字符类 [a-zA-Z0-9_] 。
  6. :匹配任何非字母、数字、下划线字符,等价于字符类 [^a-zA-Z0-9_] 。

应用实例:

  1. 用户名验证:要求用户名只包含字母、数字和下划线
  2. 密码格式验证:要求密码长度为8-12个字符
  3. 手机号码验证:要求中国大陆的手机号码格式
1
2
3
4
5
6
7
import re
result=re.match(r'\w+','455hj5h6_')
print(result)
result1=re.match(r'^.{8,12}$','455hj5456')
print(result1)
result2=re.match(r'^1[3-9]\d{9}$','13755452515')
print(result2)

正则表达式的应用

  • 数据清理:通过删除或替换不需要的字符、空格或符号来清理数据集。
  • 文本规范化:将文本数据标准化为一致的格式,例如将日期转换为标准格式或统一数值的表示。
  • 特征提取:从文本中提取可用作 ML 模型特征的特定模式或标记。
  • 数据验证:确保输入数据在输入模型之前符合指定的格式。
  • 标记化:将文本分割成单词、短语、符号或其他称为标记的有意义的元素。
  • 文本分类预处理:文本分类的预处理步骤,例如从社交媒体帖子中提取主题标签或提及。
  • 命名实体识别 (NER):识别文本中的关键元素并将其分类为预定义的类别,例如人名、组织或位置的名称。
  • 情绪分析:识别可能表明情绪的特定短语或符号。
  • 自动响应的模式匹配:识别客户查询或反馈中的模式以生成自动响应。
  • 搜索和信息检索:增强数据集中的搜索算法,以根据模式匹配查找信息或对信息进行分类。

正则表达式编译成对象

  • re 模块提供了正则表达式引擎的接口,可以让你将正则编译为对象,然后用它们来进行匹配。
1
2
3
4
import re
p = re.compile('abv?')
r=p.match('abvvvccabvvvc')
print(r)

正则表达式对象常用的方法-查找

  1. match():从字符串的开头匹配,返回一个匹配成功的字符串

    1
    2
    3
    4
    5
    6
    7
    8
    import re
    p = re.compile('abv?')
    m_m = p.match('abvvvccabvvvc')
    print(m_m)

    #相当于,等价于
    m_rm = re.match('abv?', 'abvvccabvvvc')
    print(m_rm)
  2. search():扫描整个字符串,返回一个匹配成功的字符串。

    1
    2
    3
    4
    5
    6
    7
    8
    import re
    p = re.compile('abv?')
    m_p = p.search('vvccabvvvc')
    print(m_p)

    #相当于,等价于
    m_rp = re.search('abv?', 'vvccabvvvc')
    print(m_rp)

    match和search的区别:

    • match是从头开始匹配的,如果没有则匹配失败
    • search是匹配整个字符串,没有位置限定
  3. findall():找到正则匹配的所有子字符串,返回字符串列表。

    1
    2
    3
    4
    5
    6
    7
    p1 = re.compile(r'\d+')
    m_f = p1.findall('12 drummers drumming, 11 pipers piping, 10 lords a-leaping')
    print(m_f)

    ##相当于,等价于
    m_rf = re.findall(r'\d+', '12 drummers drumming, 11 pipers piping, 10 lords a-leaping')
    print(m_rf)
  4. finditer():找到正则匹配的所有子字符串,并将它们返回为一个迭代器iterator。

1
2
3
4
5
6
7
8
9
10
iterator_f = p1.finditer('12 drummers drumming, 11 ... 10 ...')
print(iterator_f)
for m in iterator_f:
print(m.span())

#相当于,等价于
iterator_rf = re.finditer(r'\d+', '12 drummers drumming, 11 ... 10 ...')
print(iterator_rf)
for mr in iterator_rf:
print(mr.span())

正则表达式对象常用的方法-替换

  1. re.sub(pattern, repl, string, count=0, flags=0):返回已替换的字符串中的匹配项。
  2. re.subn(pattern, repl, string, count=0, flags=0):返回一个元组,元组的第一项为替换的字符串,第二项为替换了几处。
1
2
3
4
5
6
text = "aBc,ABC,aBfD"
result = re.sub('aBc?', '***', text)
print(result)

result_n = re.subn('aBc?', '***', text)
print(result_n)

正则表达式对象常用的方法-分割

  • re.split(pattern, string, maxsplit=0, flags=0):返回根据指定的正则表达式分割后的字符串
1
2
3
4
stext =  'and,  Act %  Bar。 fooD'

result_s = re.split(r'\s*[,%。]\s*', stext)
print(result_s)

输出正则表达式对象的值和位置

  • m.group():返回正则匹配的字符串
  • m.start():返回匹配的开始位置
  • m.end():返回匹配的结束位置
  • m.span():返回包含匹配 (start, end) 位置的元组
1
2
3
4
5
6
7
m2 = m_m.group()
print(m2)

m22 = m_rm.group()
print(m22)
# m3 = m_m.start()
# print(m3)

正则表达式方法中的flags参数

  • re.I(re.IGNORECASE):忽略大小写。

    1
    2
    3
    4
    5
    6
    7
    import re

    pattern = r'hello'
    text = 'Hello, World!'
    match = re.search(pattern, text, flags=re.I)
    print(match.group())
    # Hello
  • re.S(re.DOTALL):使 . 匹配任意字符,包括换行符。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    import re

    pattern = r'hello.+world'
    text = '''hello
    world'''
    match = re.search(pattern, text, flags=re.s)
    print(match.group())
    # hello
    # world
  • re.M(re.MULTILINE):多行匹配,影响 ^ 和 $ 的行为。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    import re

    # text = '123\n456\n789'
    text = '''123
    456
    789'''
    result = re.findall(r'^\d+', text, flags=re.MULTILINE)
    print(result)
    # ['123', '456', '789']
  • re.X(re.VERBOSE):忽略正则表达式中的空白和注释。

    1
    2
    3
    4
    5
    6
    7
    8
    import re
    pattern = re.compile(r'''
    \d+ # 匹配数字
    [a-z]+ # 匹配小写字母
    ''', flags=re.VERBOSE)
    result = pattern.match('123abc')
    print(result.group())
    # 123abc

贪婪匹配和惰性匹配

  • 贪婪匹配(Greedy)是正则表达式默认的匹配方式,它尽可能地匹配最长的字符串。
  • 懒惰匹配(Lazy),也称为非贪婪匹配,它尽可能地匹配最短的字符串。
1
2
3
4
5
6
7
8
9
10
11
12
import re
p = "讯飞星火认知大模型-AI大语言模型-星火大模型-科大讯飞 https://xinghuo.xfyun.cn/ 2024-04-11 10:07:25"
#贪婪匹配
G = re.match(r'讯飞.*大模型', p)
print(G.group())

#懒惰匹配
L = re.match(r'讯飞.*?大模型', p)
print(L.group())

# 讯飞星火认知大模型-AI大语言模型-星火大模型
# 讯飞星火认知大模型

综合案例:

处理数据集:用正则表达式将所有的文本数据中的逗号替换成空格,文本文件为‘re.txt’

1
2
3
4
5
6
7
8
9
10
11
import re

with open(input_file, 'r', encoding='utf-8') as f:
content = f.read()

# 使用正则表达式替换逗号
processed_content = re.sub(r',', ' ', content)

# 写入新文件
with open(output_file, 'w', encoding='utf-8') as f:
f.write(processed_content)

用正则式匹配身份证号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import re
'''
各部分说明:

[1-9]\d{5}: 地区码,第一位不能为0
(19|20): 年份前两位
\d{2}: 年份后两位
(0[1-9]|1[0-2]): 月份01-12
(0[1-9]|[12]\d|3[01]): 日期01-31
\d{3}: 序号
[0-9Xx]: 校验码

'''
res=re.match(r'^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[0-9Xx]$','110101199003079833')
print(res)

time(时间)模块与 datetime(日期)模块

time(时间)模块

  • UTC时间:世界时间
  • 本地时间:本地区的时间(东8区)
    time模块:https://docs.python.org/3/library/time.html#module-time
    datetime模块:https://docs.python.org/3/library/datetime.html#
1
2
3
4
5
import time

#时间戳
timestamp = time.time()
print(timestamp) #1970年1月1日0时0分0秒(UTC时间)到当前时间的秒数

时间戳一般用于计算时间差的

1
2
3
4
5
6
7
8
9
10
#控制程序的执行速度或者模拟耗时操作
print("某主播说:家人们,马上开始下福袋雨了啊!")
time.sleep(3)
print("福袋1发布")
time.sleep(3)
print("福袋2发布")
time.sleep(3)
print("福袋3发布")
time.sleep(3)
print("福袋4发布")

datetime(日期)模块

datetime 是 Python 内置的用于处理日期和时间的模块,提供了多种类和方法来操作时间数据。

1
2
3
4
from datetime import datetime

t = datetime.now()
print(t, type(t)) #注意这里的时间不是字符串,是一个datetime类型
1
2
3
4
5
6
7
# 获取 datetime 对象的各个部分
print(t.year) # 年:2025
print(t.month) # 月:5
print(t.day) # 日:14
print(t.hour) # 时:14
print(t.minute) # 分:30
print(t.second) # 秒:22

timedelta 表示两个 datetime 对象之间的时间差,可用于时间的加减运算。

1
2
3
4
5
6
7
8
from datetime import datetime,timedelta

v1 = datetime.now()
print(v1, type(v1))

#时间的相加(datetime + timedelta)
v2 = v1 + timedelta(days=15, minutes=5)
print(v2, type(v2))
  • datetime类型可以相加吗?等于什么? datetime 对象本身不能直接相加 但可以和 timedelta 对象相加,结果是一个新的 datetime 对象
  • datetime类型可以相减吗?等于什么? datetime 可以减去另一个 datetime,得到 timedelta 对象(表示时间差) datetime 也可以减去 timedelta,得到新的 datetime 对象

使用 strftime 方法将 time 对象 和 datetime 对象格式化为字符串

  • %Y:大写 Y 代表四位数的年份(例如,2023); %y:小写 y 代表两位数的年份(例如,23)。
  • %m:小写 m 代表月份(01到12)。
  • %d:小写 d 代表月份中的一天(01到31)。
  • %H:大写 H 代表小时(24小时制,00到23)。
  • %M:大写 M 代表分钟(00到59)。
  • %S:大写 S 代表秒(00到59)。
1
2
3
4
5
6
7
8
9
10
11
12
13
from datetime import datetime, timedelta

d1 = datetime.now()
print(d1)
dstr = d1.strftime('%Y-%m-%d %H:%M:%S')
print(dstr)


import time
current_time = time.localtime() # 获取当前时间
print(current_time, type(current_time))
tstr = time.strftime('%Y-%m-%d %H:%M:%S', current_time)
print(tstr)

日期解析(strptime)

解析(strdatetime

1
2
3
date_str = "2025-05-14 14:30:22"
parsed = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S") # 转为 datetime
print(parsed, type(parsed)) # 输出:2025-05-14 14:30:22 <class 'datetime.datetime'>

时区处理

默认的 datetime 对象是无时区信息的(tzinfo=None)。如需处理时区,可使用 pytz 或 Python 3.9+ 内置的 zoneinfo 模块:

1
2
3
4
5
6
7
8
9
from datetime import datetime
from zoneinfo import ZoneInfo # Python 3.9+

# 创建带时区的 datetime 对象
now_utc = datetime.now(ZoneInfo("UTC"))
now_shanghai = datetime.now(ZoneInfo("Asia/Shanghai"))

print(now_utc.tzinfo) # 输出:UTC
print(now_shanghai) # 输出:2025-05-14 22:30:22+08:00