常用模块定义、导入、优化详解
1、模块介绍
1.1、定义:模块:用来从逻辑上组织python代码(变量、函数、类、逻辑:实现有个功能)
本质就是.py结尾的python文件(文件名:test.py,对应的模块名是test)
包:是用来从逻辑上组织模块的,本质就是一个目录或文件夹(必须带有__init__.py的文件)
1.2、导入方法:import moudle_name1,moudle_name2
from moudle_name import *
#不提倡这种导入方法,等于把moudle_name中的代码在当前文件执行一次,容易冲突
from moudle_name import name1,name2,name3
from moudle_name import logger as logger_ls
用from也可以,导入某个特定方法,另起别名,就可以调用不怕冲突了
1.2.2、导入包的本质:解释执行这个包下的__init__.py文件
想要调用导入的包下的别的名字的文件(test1.py)
可以在修改那个包下的 __init__.py 文件,将 from . import test1 写入
就能在当前的文件里
1.3、调用:用import moudle_name1,moudle_name2这种方法调用导入
调用的时候直接 moudle_name1. 调用才可以
1.4、import的本质:将moudle_name中的代码解释一遍,赋值给moudle_name这个变量,
moudle_name.name()才能调用
from moudle_name import name 本质:只把moudle_name模块当中的name在当前文及中执行了一遍,
直接name()就能执行了
os.path.dirname() #获取当前(文件或目录)的目录名,想返回前两层,就来两次这个方法
__file__ #当前文件名
os.path.abspath(__file__) #获取这个文件的绝对路径
1.5、导入优化
在当前文件的同级目录下定义一个module_test.py模块,内有test()函数,print("in the module_test")
import module_test
def logger():
module_test.test() #调用module_test模块中的test()方法
print("in the logger")
def search():
module_test.test() #调用module_test模块中的test()方法
print("in the search")
logger()
search()
--->
in the module_test
in the logger
in the module_test
in the search
######如果多次调用module_test模块中的test()方法,在寻找module_test模块的过程会浪费时间,因为每一次调用
都会寻找一次module_test模块这个模块,改怎么优化呢???
如下:
from module_test import test #开头直接写死,不让他寻找,直接告诉他在哪个地方
def logger():
test()
print("in the logger")
def search():
test()
print("in the search")
logger()
search() #输出一样
2、模块的分类
2.1、标准库,如:os、sys、time
2.2、开源模块:第三方模块,别人写的模块上传到网上,自己下载下来可以直接用
2.3、自定义模块
3、常用内置模块:
1、time & datetime
2、random
3、os
4、sys
5、shutil
6、json & picle
7、shelve
8、xml处理
9、yaml处理
10、configparser
11、hashlib
12、subprocess
13、logging
14、re正则表达式
3.1、time & datetime 模块
在python里,常用几种格式来表示时间:
1)时间戳:从当前时间减去1970年1月1日0分0秒,这个时间间隔的秒数,time.time()
2)格式化的时间字符串,如:2019-09-25 16:12:54
3)元组(struct_time(tuple))共9个元素
3.1.1、简单调用方法1(time)
三种格式的之间的相互转换方法:
a=time.time() #获取当前时间戳
time.sleep(1) #睡眠1秒
c=time.gmtime() #将时间戳转换为元组的形式(结果为UTC时区),为空默认为当前的时间
d=time.localtime() #同上(结果为本地时间,我们是UTC+8),为空默认为当前的时间
e=time.gmtime(912422141) #将时间戳为"912422141"的时间转换为结构化的元组的形式(UTC时区)
f=time.localtime(912422141) #将时间戳为"912422141"的时间转换为结构化的元组的形式(本地时区)
g=time.strftime("%Y-%m-%d %H:%M:%S",f) #获取f的格式化的字符串的形式,strftime("格式","元组")
h=time.strptime("2019-10-08 14:07:28","%Y-%m-%d %H:%M:%S")
#获取输入的字符串时间的格式化的字符串形式,strptime("字符串","格式")
print(a)
print(c)
print(d)
print(d.tm_year) #可以取出9项中其中某一项,如取出年份:d.tm_year
print(e)
print(f)
print(time.mktime(d)) #将结构化的元组表示的时间转换为时间戳
print(g)
--->
1569569812.8157363
time.struct_time(tm_year=2019, tm_mon=9, tm_mday=27, tm_hour=7, tm_min=36, tm_sec=52, tm_wday=4, tm_yday=270, tm_isdst=0)
time.struct_time(tm_year=2019, tm_mon=9, tm_mday=27, tm_hour=15, tm_min=36, tm_sec=52, tm_wday=4, tm_yday=270, tm_isdst=0)
2019
time.struct_time(tm_year=1998, tm_mon=11, tm_mday=30, tm_hour=10, tm_min=35, tm_sec=41, tm_wday=0, tm_yday=334, tm_isdst=0)
time.struct_time(tm_year=1998, tm_mon=11, tm_mday=30, tm_hour=18, tm_min=35, tm_sec=41, tm_wday=0, tm_yday=334, tm_isdst=0)
1569569812.0
2019-10-08 14:07:28
3.1.2、 简单调用方法2(datetime)
import datetime
a=datetime.datetime.now() + datetime.timedelta(-3) #减3天
b=datetime.datetime.now() #当前时间
c=datetime.datetime.now() + datetime.timedelta(+3) #加3天
d=datetime.datetime.now() + datetime.timedelta(hours=-5) #减5小时
e=datetime.datetime.now() + datetime.timedelta(hours=+5) #加5小时
f=datetime.datetime.now() + datetime.timedelta(minutes=-40) #减40分钟
g=datetime.datetime.now() + datetime.timedelta(minutes=+40) #加40分钟
h=datetime.datetime.now() + datetime.timedelta(hours=+5) + datetime.timedelta(minutes=+10) #加5天10分钟
print("a =",a)
print("b =",b)
print("c =",c)
print("d =",d)
print("e =",e)
print("f =",f)
print("g =",g)
print("h =",h)
--->
a = 2019-10-05 15:46:53.994597
b = 2019-10-08 15:46:53.994597
c = 2019-10-11 15:46:53.994597
d = 2019-10-08 10:46:53.994597
e = 2019-10-08 20:46:53.994597
f = 2019-10-08 15:06:53.994597
g = 2019-10-08 16:26:53.994597
h = 2019-10-08 20:56:53.994597
3.2、random模块
import random
random.random() #生成随机浮点数,默认[0,1)之间的
random.uniform(1,4) #生成随机浮点数,跟参数
random.randint(1,2) #生成随机整数,必须跟参数范围,1和2都能取到
random.randrange(1,5) #生成随机整数,必须跟参数范围,1能取到,2娶不到
random.choice([1,2,34,5]) #choice("序列"),随机取一个元素。序列包含:字符串、列表、元组
random.choice('dadasds')
random.choice((4,5,6,7,8))
random.sample('hello',2) #sample('序列',2),第一个参数是序列,第二个参数是长度
l = [1,2,3,4,5,6,7,8,9,10]
random.shuffle(l) #洗牌功能,打乱顺序
--->
0.740239330593416
1.8360962683299822
2
1
34
s
8
['h', 'o']
[6, 4, 9, 3, 1, 5, 10, 8, 7, 2]
应用:随机4位验证码生成
import random
checkcode = ''
for i in range(4):
current=random.randrange(0,4) #[0,1,2,3]随机取一个
if current == i: #猜i与current是否一样
tmp = chr(random.randint(65,90)) #一样就取一个字母
else:
tmp = random.randint(0,9) #不一样就取一个数字
checkcode += str(tmp) #将数字或字母转换成字符串
print(checkcode)
3.3、os模块
import os
os.getcwd() #获取当前路径
os.chdir("D:\\Python3.7.4") #改变路径,用双斜杠的方式可以
os.chdir(r"D:\Python3.7.4") #前面加'r',单斜杠就可以了,推荐使用这种方法
os.getcwd()
os.curdir #返回当前目录
os.pardir #返回上一级目录
os.makedirs(r"C:\a\b\c") #递归地创建文件夹,可生成多层递归目录
os.removedirs(r"C:\a\b\c") #递归地删除文件夹,若目录为空则删除,并递归到上一级,以此类推
os.makedir(r"C:\a") #创建文件夹,不能递归
os.rmdir(r"C:\a") #删除文件夹,不能递归,只删除一层
os.listdir('') #列出指定目录下所有文件和目录,包含隐藏文件,以列表方式打印
os.remove() #删除一个文件
os.rename('old name','new name') #文件/目录改名
os.stat('r'D:\\2019住房公积金提取资料.zip'') #获取文件/目录的信息
os.sep #获取当前操作系统的路径分隔符,windows为'\\',linux为'//'
os.linesep #获取当前操作系统的换行分隔符,win为'\r\n',linux为'\n'
os.pathsep #获取当前不同路径分隔符,win为';',linux为':'
os.name #输出字符串指示当前使用平台,win->'nt'; Linux->'posix'
os.system("bash command") #运行shell命令,直接显示
os.environ #获取系统环境变量
os.path.abspath(path) #返回path规范化的一个文件绝对路径
os.path.split(path) #将path分割成目录和文件名二元组返回
os.path.dirname(path) #返回path的目录,其实就是os.path.split(path)的第一个元素
os.path.basename(path) #返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path) #如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path) #如果path是绝对路径,返回True
os.path.isfile(path) #如果path是一个存在的文件,返回True,否则返回False
os.path.isdir(path) #如果path是一个存在的目录,则返回True,否则返回False
os.path.join(path1[, path2[, ...]]) #将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path) #返回path所指向的文件或者目录的最后存取时间(时间戳)
os.path.getmtime(path) #返回path所指向的文件或者目录的最后修改时间(时间戳)
--->
'D:\\Python3.7.4\\项目1'
'D:\\Python3.7.4\\项目1'
'.'
'..'
['.idea', 'day1', 'day10', 'day11', 'day12', 'day2', 'day3', 'day4', 'day5', 'day8', 'day9', 'venv']
os.stat_result(st_mode=33206, st_ino=2251799813775687, st_dev=500065, st_nlink=1, st_uid=0, st_gid=0, st_size=240508, st_atime=1554775053, st_mtime=1554775022, st_ctime=1554775022)
'\\'
3.4、sys模块
import sys
sys.argv #命令行参数List,第一个元素是程序本身路径,返回跟的参数
sys.exit(n) #退出程序,正常退出时exit(0)
sys.version #获取Python解释程序的版本信息
sys.maxint #最大的Int值
sys.path #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform #返回操作系统平台名称
sys.stdout.write('please:') #打印文件到标准输出,类似于print()
val = sys.stdin.readline()[:-1]
3.5、shutil模块,copy文件用的
参考: https://www.cnblogs.com/wupeiqi/articles/4963027.html
import shutil
#copyfileobj用法():
f1 = open("笔记1",encoding='utf-8')
f2 = open("笔记3","w",encoding='utf-8')
shutil.copyfileobj(f1,f2[, length]) #f1是原文件,f2是目标文件,将f1复制到f2,length可有可无
#copyfile用法():
shutil.copyfile("笔记1","笔记2") #不用打开文件,直接写文件名
shutil.copymode(src, dst) #仅拷贝权限,内容、组、用户均不变
shutil.copystat(src, dst) #拷贝状态的信息,包括:mode bits, atime, mtime, flags
shutil.copy(src, dst) #拷贝文件和权限
shutil.copy2(src, dst) #拷贝文件和状态信息
shutil.copytree(src, dst, symlinks=False, ignore=None) #递归的去拷贝文件
shutil.rmtree(path[, ignore_errors[, onerror]]) #递归的去删除文件
shutil.move(src, dst) #递归的去移动文件
shutil.make_archive(base_name, format, root_dir, ...)
创建压缩包并返回文件路径,例如:zip、tar
base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
如:www =>保存至当前路径
如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
root_dir: 要压缩的文件夹路径(默认当前目录)
owner: 用户,默认当前用户
group: 组,默认当前组
logger:用于记录日志,通常是logging.Logger对象
shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:
import zipfile
# 压缩
z = zipfile.ZipFile('laxi.zip', 'w')
<details>
<summary>点击查看代码</summary>
</details>
z.write('a.log')
z.write('data.data')
z.close()
# 解压
z = zipfile.ZipFile('laxi.zip', 'r')
z.extractall()
z.close()
---------------------------------------------------------------------------------------
import tarfile
# 压缩
tar = tarfile.open('your.tar','w')
tar.add('/Users/wupeiqi/PycharmProjects/bbs2.zip', arcname='bbs2.zip')
tar.add('/Users/wupeiqi/PycharmProjects/cmdb.zip', arcname='cmdb.zip')
tar.close()
# 解压
tar = tarfile.open('your.tar','r')
tar.extractall() # 可设置解压地址
tar.close()
3.6、json & pickle模块
用于序列化的两个模块
· json, 用于字符串和python数据类型间进行转换, 可与其他语言交互
· pickle, 用于python特有的类型 和 python的数据类型间进行转换, 支持python所有的数据类型
json提供了四个功能:dumps、dump、loads、load
pickle提供了四个功能:dumps、dump、loads、load
3.7、shelve模块
shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式
1、先是持久化保存
import shelve
d = shelve.open('shelve_test') # 打开一个文件
info = {'name':'lishang','age':'18','girl':'zxm'}
name = ["alex", "rain", "test"]
date = datetime.datetime.now()
d["name"] = name # 持久化列表
d["info"] = info # 持久化字典
d["date"] = date # 持久化一个时间格式
d.close()
2、再是读取出来
import shelve
d = shelve.open('shelve_test') # 打开一个文件
print(d.get("name"))
print(d.get("info"))
print(d.get("date"))
--->
['alex', 'rain', 'test']
{'name': 'lishang', 'age': '18', 'girl': 'zxm'}
2019-10-10 11:01:27.788940
3.8、xml处理模块
xml的格式如下,通过<>节点来区别数据结构
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank updated="yes">69</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml
import xml.etree.ElementTree as ET
tree = ET.parse("xmltest.xml")
root = tree.getroot()
print(root.tag)
#遍历xml文档
for child in root:
print(child.tag, child.attrib)
for i in child:
print(i.tag,i.text)
#只遍历year 节点
for node in root.iter('year'):
print(node.tag,node.text)
修改和删除xml文档内容
import xml.etree.ElementTree as ET
tree = ET.parse("xmltest.xml")
root = tree.getroot()
#修改
for node in root.iter('year'):
new_year = int(node.text) + 1
node.text = str(new_year)
node.set("updated","yes")
tree.write("xmltest.xml")
----------------------------------------------------------------------------------
#删除node
for country in root.findall('country'):
rank = int(country.find('rank').text)
if rank > 50:
root.remove(country)
tree.write('output.xml')
自己创建xml文档
import xml.etree.ElementTree as ET
new_xml = ET.Element("personinfolist")
personinfo = ET.SubElement(new_xml, "personinfo", attrib={"enrolled": "yes"})
name = ET.SubElement(personinfo, "name")
name.text = 'Li Shang'
age = ET.SubElement(personinfo, "age", attrib={"checked": "no"})
sex = ET.SubElement(personinfo, "sex")
age.text = '18'
personinfo2 = ET.SubElement(new_xml, "personinfo", attrib={"enrolled": "no"})
name = ET.SubElement(personinfo2, "name")
name.text = 'Zhao xiaomeng'
age = ET.SubElement(personinfo2, "age")
age.text = '20'
et = ET.ElementTree(new_xml) # 生成文档对象
et.write("test.xml", encoding="utf-8", xml_declaration=True)
ET.dump(new_xml) # 打印生成的格式
---> ######cat test.xml
<?xml version='1.0' encoding='utf-8'?>
<personinfolist>
<personinfo enrolled="yes">
<name>Li Shang</name>
<age checked="no">18</age>
<sex />
</personinfo>
<personinfo enrolled="no">
<name>Zhao xiaomeng</name>
<age>20</age>
</personinfo>
</personinfolist>
3.9、yaml处理模块
参考:https://pyyaml.org/wiki/PyYAMLDocumentation
要手动下载安装pyyaml
pip install pyyaml
3.10、configparser模块
用于生成和修改常见配置文档,当前模块的名称在 python 3.x 版本中变更为 configparser
- 来看一个好多软件的常见文档格式如下
[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes
[bitbucket.org]
User = hg
[topsecret.server.com]
Port = 50022
ForwardX11 = no
- 如果想用python生成一个这样的文档怎么做呢?
###写一个配置文件
import configparser
config = configparser.ConfigParser()
config["DEFAULT"] = {'ServerAliveInterval': '45',
'Compression': 'yes',
'CompressionLevel': '9'}
config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'
config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '50022' # mutates the parser
topsecret['ForwardX11'] = 'no' # same here
config['DEFAULT']['ForwardX11'] = 'yes'
with open('example.ini', 'w') as configfile:
config.write(configfile)
- 写完了还能读出来
import configparser
conf = configparser.ConfigParser()
conf.read("example.ini")
print(conf.sections())
print(conf['bitbucket.org']['user'])
print(conf['topsecret.server.com']['host port'])
for key in conf['bitbucket.org']: #还能循环
print(key)
--->
['bitbucket.org', 'topsecret.server.com']
hg
50022
user
serveraliveinterval
compression
compressionlevel
forwardx11
- 还能增删改查
###删掉topsecret.server.com这个节点
sec = conf.remove_section('topsecret.server.com')
conf.write(open('example.ini', "w"))
3.11、hashlib模块
- 用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
import hashlib
m = hashlib.md5() #md5加密
m.update(b"Hello")
print(m.hexdigest())
m.update(b"It's me")
print(m.hexdigest()) #这一次不仅是"It's me",而是"HelloIt's me"
m2 = hashlib.md5()
m2.update(b"HelloIt's me") #验证第二个是不是前两个的累加
print(m2.hexdigest())
ss = hashlib.sha256() #sha256加密
ss.update(b'admin')
print(ss.hexdigest())
--->
8b1a9953c4611296a827abf8c47804d7
5ddeb47b2f925ad0bf249c52e342728a #第二和第三是一样的
5ddeb47b2f925ad0bf249c52e342728a
- 还不够吊?python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密
散列消息鉴别码,简称HMAC,是一种基于消息鉴别码MAC(Message Authentication Code)的鉴别机制。
使用HMAC时,消息通讯的双方,通 过验证消息中加入的鉴别密钥K来鉴别消息的真伪;
一般用于网络通信中消息加密,前提是双方先要约定好key,就像接头暗号一样,然后消息发送把用key把消息加密,接收方用key + 消息明文再加密,拿加密后的值 跟 发送者的相对比是否相等,这 样就能验证消息的真实性,及发送者的合法性了。
import hmac
h = hmac.new(b'12345','你是250'.encode(encoding="utf-8"))
print(h.hexdigest())
--->
e1635b86f44e1b324dfb2bc96076ee0f
3.12、subprocess模块
3.13、logging模块
logging的高级应用
logging模块采用了模块化设计,主要包含四种组件:
1、Loggers:记录器,提供应用程序代码能直接使用的接口;
2、Handlers: 处理器,江记录器产生的日志发送只目的地;
3、Filters:过滤器,提供更好的颗粒控制,决定那些日志会被输出;
4、Formatters:格式化器,设置日志内容的组成结构和消息字段。

Loggers 记录器
1、提供应用程序的调用接口
logger = logging.getLogger(__name__)
logger是单例的
2、决定日志记录的级别
logger.setLevel()
3、将日志内容传递到相关联的handlers中
logger.addHandler()和logger.removeHandler()
Handlers 处理器
他们将日志分发到不同的目的地。可以是文件、标准输出、邮件、或者通过socket、http等协议发送到任何地方。
StreamHandle
标准输出stdout(如显示器)分发器。
创建方法:sh = logging.StreamHandle(stream=None)
FileHandler
将日志保存到磁盘文件的处理器。
创建方法:fh = logging.FileHandler(filename, mode='a', encoding=None, delay=False)
setFormatter(): 设置当前handler对象使用的消息格式。
Formatters 格式
Formatter对象用来最终设置日志信息的顺序、结构和内容。
其构造方法魏
ft = logging.Formatter.__init__(fmt=None, datefmt=None, style='%')
datefmt默认是%Y-%m-%d %H:%M:%S样式的
style参数默认百分符%, 这表示%(<dictionary key>)s格式的字符串

3.14、re正则表达式模块
常用正则·表达式符号
'.' 默认匹配除\n(换行)之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
'^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
'$' 匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以
'*' 匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac") 结果为['abb', 'ab', 'a']
'+' 匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
'?' 匹配前一个字符1次或0次
'{m}' 匹配前一个字符m次
'{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
'|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
'(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c
'\A' 只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的
'\Z' 匹配字符结尾,同$
'\d' 匹配数字0-9
'\D' 匹配非数字
'\w' 匹配[A-Za-z0-9]
'\W' 匹配非[A-Za-z0-9]
'\s' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'
'(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city")
结果{'province': '3714', 'city': '81', 'birthday': '1993'}
最常用的匹配语法
re.match 从头开始匹配
re.search 匹配包含
re.findall 把所有匹配到的字符放到以列表中的元素返回
re.splitall 以匹配到的字符当做列表分隔符
re.sub 匹配字符并替换
实例
import re
re.match("^.+","lishang23andzhaoxiaomeng24") #从头匹配任意一个字符一次或多次
<re.Match object; span=(0, 26), match='lishang23andzhaoxiaomeng24'>
re.search("z[a-z]+g","lishang23andzhaoxiaomeng24") #从头匹配'z'开头,后跟任意字母一个或多个,再跟'g'
<re.Match object; span=(12, 24), match='zhaoxiaomeng'>
re.search("#.+#","13213#hello#") #匹配以'#'开头,后跟任意字符任意个,再跟一个'#'
<re.Match object; span=(5, 12), match='#hello#'>
re.search("aal?","aalexaaa") #先匹配到aa,再匹配问号前面的l零次或一次,这里匹配到了一次
<re.Match object; span=(0, 3), match='aal'>
re.search("aal?","aaexaaa") #先匹配到aa,再匹配问号前面的l零次或一次,这里匹配到了零次
<re.Match object; span=(0, 2), match='aa'>
re.search("[0-9]{3}","aa1l2e345xaaa") #匹配数字三次
<re.Match object; span=(6, 9), match='345'>
re.search("[0-9]{1,3}","aa1l2e345xaaa") #匹配数字一次或三次,但只匹配一次就返回
<re.Match object; span=(2, 3), match='1'>
#####################想要返回匹配到的多个字符串都返回,用findall
re.findall("[0-9]{1,3}","aa1l2e345xaaa") #匹配数字一次到三次,用findall全部返回一个列表的形式
['1', '2', '345']
re.search("abc|ABC","ABCBabcCD").group() #匹配'abc'或'ABC',用group()取出返回的字符串
'ABC'
re.findall("abc|ABC","ABCBabcCD") #全部返回,但findall没有group方法
['ABC', 'abc']
re.search("abc{2}","lishangabccc") #匹配'ab'和两个'c',因此返回'abcc'
<re.Match object; span=(7, 11), match='abcc'>
re.search("(abc){2}","lishangabcabcc")
<re.Match object; span=(7, 13), match='abcabc'> #把abc括起来,就成了匹配两次'abc'这个整体两次
re.search("(abc){2}(\|\|=){2}","lishangabcabc||=||=") #匹配'abc'两次在跟'||='两次
<re.Match object; span=(7, 19), match='abcabc||=||='>
########################分组匹配
re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict()
{'province': '3714', 'city': '81', 'birthday': '1993'}
re.search("(?P<province>[0-9]{2})(?P<city>[0-9]{2})(?P<xian>[0-9]{2})(?P<birthday>[0-9]{8})","371481199306143242").group("city")
'14'
re.split("[0-9]+","abc12de3f45GH") #以数字做分隔符,返回剩下的字符串
['abc', 'de', 'f', 'GH']
re.sub("[0-9]+","|","abc12de3f45GH",count=2) #替换,将数字换成'|',替换两次
'abc|de|f45GH'
- 仅需轻轻知道的几个匹配模式
re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)
M(MULTILINE): 多行模式,改变'^'和'$'的行为(参见上图)
S(DOTALL): 点任意匹配模式,改变'.'的行为
import re
re.search("[a-z]+","sadsaASA",flags=re.I) #忽略大小写,
<re.Match object; span=(0, 8), match='sadsaASA'>
```2022-03-24 16:32:37 星期四

浙公网安备 33010602011771号