15.常用模块(二)

【一】pickle模块

1)序列化方法(dumps)反序列化方法(loads)

import pickle

eg = {'a': 1, 'b': 2}
# 字典转二进制
eg_byt = pickle.dumps(eg)
print(eg_byt)
# 二进制转字典
eg_dic = pickle.loads(eg_byt)
print(eg_dic)

2)写入(dump)读取(load)

  • 写入的是乱码
  • 可不知道文件后缀
import pickle

eg = {'a': 1, 'b': 2}
# 写入
with open('eg', 'wb') as f:
    pickle.dump(eg, f)
# 读取
with open('eg', 'rb') as f:
    eg = pickle.load(f)
print(eg)

【二】subprocess模块

  • 启动一个新的进程

  • 使用我们自己的电脑去链接别人的电脑 (socket模块)

1)使用

import subprocess

res = subprocess.Popen('diraaa', shell=True,
                       stdout=subprocess.PIPE,  # 管道 负责存储正确的信息
                       stderr=subprocess.PIPE  # 管道 负责存储错误信息
                       )
print(res)  # <subprocess.Popen object at 0x000001ABB1970310>
print(res.stdout.read().decode('gbk'))  # tasklist执行之后的正确结果返回
print(res.stderr.read().decode('gbk'))

2)run方法

import subprocess

def runcmd(command):
    ret = subprocess.run(command,  # 子进程要执行的命令
                         shell=True,  # 执行的是shell的命令
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE,
                         # encoding="utf-8",
                         timeout=1)
    # returncode属性是run()函数返回结果的状态。
    if ret.returncode == 0:
        print("success:", ret.stdout)
    else:
        print("error:", ret)

runcmd(["dir", '/b'])  # 序列参数
# success: CompletedProcess(args=['dir', '/b'], returncode=0, stderr='')
runcmd("exit 1")  # 字符串参数
# error: CompletedProcess(args='exit 1', returncode=1, stdout='', stderr='')

3)call方法

import subprocess

subprocess.call(['python', '--version'])
# Python 3.11.8

【三】re模块(正则语法)

1)字符组

import re
res = re.findall('正则模式','文本')
eg = 'abcdABCD1234'
res = re.findall('[0-9]',eg)
res = re.findall('[a-z]',eg)
res = re.findall('[A-Z]',eg)
res = re.findall('[0-9a-zA-Z]',eg)

2)元字符

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

3)量词

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

4)位置元字符

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

5)重复匹配

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

6)字符集

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

7)分组匹配

  • | 或条件
  • ()优先匹配
  • [^] 除了当前字符组以外的其他字符

8)贪婪匹配

  • 贪婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配
  • 非贪婪匹配:加上?转为非贪婪匹配模式,在满足匹配时,匹配尽可能短的字符串

几个常用的非贪婪匹配,Pattern

  • *? 重复任意次,但尽可能少重复
  • +? 重复1次或更多次,但尽可能少重复
  • ?? 重复0次或1次,但尽可能少重复
  • {n,m}? 重复n到m次,但尽可能少重复
  • {n,}? 重复n次以上,但尽可能少重复

9)常用方法

1.查找结构(findall)

import re

name_str = "Dream yuan Justin"
# 返回所有满足匹配条件的结果,放在列表里
result = re.findall('a', name_str)
print(result)	# 结果 : ['a', 'a']

2.查找结构(search)

import re

name_str = "Dream yuan Justin"
# 找到第一个然后返回该信息的对象,该对象可以通过调用group()方法得到匹配的字符串,没有则返回None。
result = re.search('a', name_str).group()
print(result)	# 结果 : 'a'

3.查找结果(match)

import re

name_str = 'abc'
# 同search,不过仅在字符串开始处进行匹配
result = re.match('a', 'abc').group()
print(result)	# 结果 : 'a'

4.切割(split)

import re

name_str = 'abcd'
# 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'c'分割
result = re.split('[ac]', name_str)
print(result)  # ['', 'b', 'd']

5.指定个数替换(sub)

import re

name_str = 'a1b2c3'
# 将数字替换成'x',参数2表示只替换2个
result = re.sub('\d', 'X', name_str, 2)
print(result)  # aXbXc3

6.替换全部(subn)

import re

name_str = 'a1b2c3'
# 将数字替换成'H',也可指定替换个数
result = re.subn('\d', 'X', name_str)
print(result)  # ('aXbXcX', 3)

7.编译正则表达式(compile)

import re

# 将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
obj = re.compile('\d{3}')
# 正则表达式对象调用search,参数为待匹配的字符串
ret = obj.search('abc123eeee')
print(ret.group())  # 结果 : 123

8.匹配结果为迭代器(finditer)

import re

# finditer返回一个存放匹配结果的迭代器
ret = re.finditer('\d', 'ds3sy4784a')
print(ret)
# <callable_iterator object at 0x10195f940>
print(next(ret).group())
# 查看第一个结果 3
print(next(ret).group())
# 查看第二个结果 4
print([i.group() for i in ret])
# 查看剩余的所有结果 ['7', '8', '4']

10)正则方法优先级

1.findall的优先级查询

import re

# 这是因为findall会优先把匹配结果组里内容返回
ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
print(ret)  # ['oldboy']
# 如果想要匹配结果,取消权限即可
ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')
print(ret)  # ['www.oldboy.com']

2.split的优先级查询

import re

ret = re.split("\d+", "abc1def2ghi")
print(ret)  # 结果 : ['abc', 'def', 'ghi']
# 没有()的没有保留所匹配的项
ret = re.split("(\d+)", "abc1def2ghi")
print(ret)  # 结果 : ['abc', '1', 'def', '2', 'ghi']
# 有()的却能够保留了匹配的项

【补】常用正则表达式

场景 正则表达式
用户名 ^[a-z0-9_-]{3,16}$
密码 ^[a-z0-9_-]{6,18}$
手机号码 ^(?:\+86)?1[3-9]\d{9}$
颜色的十六进制值 ^#?([a-f0-9]
电子邮箱 ^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+\.[a-z]+$
URL ^(?:https://
IP 地址 ((2[0-4]\d
HTML 标签 ^<([a-z]+)([^<]+)*(?:>(.*)<\/\1>
utf-8编码下的汉字范围 ^[\u2E80-\u9FFF]+$
posted on 2024-04-24 16:41  晓雾-Mist  阅读(3)  评论(0编辑  收藏  举报