常用模块
Posted sxy-blog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常用模块相关的知识,希望对你有一定的参考价值。
常用模块
模块
定义:在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。
为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。
在Python中,一个.py文件就可以称之为一个模块。
优点:
1.最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块。
2.使用模块还可以避免函数名和变量名冲突。每个模块有独立的命名空间,因此相同名字的函数和变量完全可以分别存在不同的模块中,所以,我们自己在编写模块时,不必考虑名字会与其他模块冲突。
分类:
模块分为三种:
内置标准模块(又称标准库)执行help(‘modules’)查看所有python自带模块列表
第三方开源模块,可通过pip install 模块名 联网安装
自定义模块
模块的导入与调用
import module_a #导入 from module import xx from module.xx.xx import xx as rename #导入后重命令 from module.xx.xx import * #导入一个模块下的所有方法,不建议使用 module_a.xxx #调用
模块查找路径
发现,自己写的模块只能在当前路径下的程序里才能导入,换一个目录再导入自己的模块就报错说找不到了, 这是为什么?
这与导入模块的查找路径有关
import sys
print(sys.path)
输出(注意不同的电脑可能输出的不太一样)
[‘‘, ‘/Library/Frameworks/Python.framework/Versions/3.6/lib/python36.zip‘,
‘/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6‘,
‘/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload‘,
‘/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages‘]
你导入一个模块时,Python解释器会按照上面列表顺序去依次到每个目录下去匹配你要导入的模块名,只要在一个目录下匹配到了该模块名,就立刻导入,不再继续往后找。
注意:列表第一个元素为空,即代表当前目录,所以你自己定义的模块在当前目录会被优先导入。
我们自己创建的模块若想在任何地方都能调用,那就得确保你的模块文件至少在模块路径的查找列表中。
我们一般把自己写的模块放在一个带有“site-packages”字样的目录里,我们从网上下载安装的各种第三方的模块一般都放在这个目录。
os模块
os 模块提供了很多允许你的程序与操作系统直接交互的功能。
import os os.getcwd() # 返回当前工作目录,即当前脚本的工作路径 os.listdir() # 返回指定路径下所有的目录名和文件名 os.path.basename() # 获取文件名 os.path.join(dir,fliename) # 将目录名和文件名结合起来 os.path.split() # 将文件名和目录分开,返回一个元组 os.path.dirname() #返回指定路径的上一层路径 print(os.path.dirname(‘D:OldBoy_Luffy代码基础练习chapter4os_sys.py‘)) # (‘D:OldBoy_Luffy代码基础练习chapter4‘, ‘os_sys.py‘) os.path.abspath() # 返回绝对路径 #常用用法 os.path.abspath(__file__) # 当前文件的绝对路径,包含文件名 #__fil__是当前目录起的相对路径 在终端中打印__file__显示的是相对路径 pycharm是从根目录开始的,因此在pycharm中__file__就是绝对路径 os.path.isfile() # 检验给出的路径是否是一个文件 os.path.isdir() # 检验给出的路径是否是一个目录 os.path.isabs() # 检验路径是否为绝对路径 os.path.exists() # 检验给出的路径是否真的存在 os.stat(filr) # 获取文件属性 os.remove() # 用来删除一个文件 os.removedirs() # 删除多个目录 os.path.splitext(‘) # 分离扩展名 print(os.path.splitext(‘chapter4os_sys.py‘)) # (‘chapter4os_sys‘, ‘.py‘) os.getenv("HOME") # 读取操作系统环境变量HOME的值 os.environ # 返回操作系统所有的环境变量 os.environ.setdefault(‘HOME‘,‘/home/alex‘) # 设置系统环境变量,仅程序运行时有效 os.linesep # 给出当前平台使用的行终止符 os.name # 指示你正在使用的平台 对于Windows,它是‘nt‘,而对于Linux/Unix用户,它是‘posix‘ os.rename(old, new) # 重命名 os.makedirs(r“c:python est”) # 创建多级目录 os.mkdir(“test”) # 创建单个目录 os.chmod(file) # 修改文件权限与时间戳 os.path.getsize(filename) # 获取文件大小 os.chdir(dirname) # 改变工作目录到dirname os.get_terminal_size() # 获取当前终端的大小 os.kill(10884,signal.SIGKILL) # 杀死进程
sys模块
sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0) sys.version 获取Python解释程序的版本信息 sys.maxint 最大的Int值
sys.path 返回模块的搜索路径,模块导入时按照搜索路径依次搜索模块,初始化时使用PYTHONPATH环境变量的值
sys.platform 返回操作系统平台名称 sys.stdout.write(‘please:‘) #标准输出 , 引出进度条的例子, 注,在py3上不行,可以用print代替 val = sys.stdin.readline()[:-1] #标准输入 sys.getrecursionlimit() #获取最大递归层数 当递归次数过多会导致栈溢出 sys.setrecursionlimit(1200) #设置最大递归层数 sys.getdefaultencoding() #获取解释器默认编码 sys.getfilesystemencoding #获取内存数据存到文件里的默认编码
time模块
在Python与时间处理有关的模块是time,datetime。
我们写程序时对时间的处理可以归为以下3种:
时间的显示,在屏幕显示、记录日志等
时间的转换,比如把字符串格式的日期转成Python中的日期类型
时间的运算,计算两个日期间的差值等
在Python中,通常有这几种方式来表示时间:
时间戳(timestamp), 表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。例子:1554864776.161901
格式化的时间字符串,比如“2020-10-03 17:54”
元组(struct_time)共九个元素。由于Python的time模块实现主要调用C库,所以各个平台可能有所不同,mac上:time.struct_time(tm_year=2020, tm_mon=4, tm_mday=10, tm_hour=2, tm_min=53, tm_sec=15, tm_wday=2, tm_yday=100, tm_isdst=0)
索引(Index) 属性(Attribute) 值(Values) 0 tm_year(年) 比如2011 1 tm_mon(月) 1 - 12 2 tm_mday(日) 1 - 31 3 tm_hour(时) 0 - 23 4 tm_min(分) 0 - 59 5 tm_sec(秒) 0 - 61 6 tm_wday(weekday) 0 - 6(0表示周日) 7 tm_yday(一年中的第几天) 1 - 366 8 tm_isdst(是否是夏令时) 默认为-1
UTC时间
UTC(Coordinated Universal Time,世界协调时)亦即格林威治天文时间,世界标准时间。在中国为UTC+8,又称东8区。
time模块的方法
time.localtime() # 将一个时间戳转换为当前时区的struct_time 没有参数就默认为当前时间 time.gmtime() # 将一个时间戳转换为UTC时间的struct_time time.time() # 返回当前时间的时间戳 time.mktime() # 将一个struct_time 转换为时间戳、 time.sleep() # 线程推迟指定时间后再运行 time.asctime() # 把一个时间元组转化成’Sun Oct 1 12:04:38 2019的形式 time.ctime() # 把一个时间戳转换为’Sun Oct 1 12:04:38 2019的形式 time.strftime() # 把一个时间元组转换为格式化的字符串。 time.strftime(“%Y-%m-%d %X”, time.localtime()) #输出’2017-10-01 12:14:23’ time.strptime() # 把一个格式化的字符串转换成struct_time time.strptime(‘2017-10-3 17:54’,”%Y-%m-%d %H:%M”) # 需要告诉程序字符串的格式 #输出 time.struct_time(tm_year=2017, tm_mon=10, tm_mday=3, tm_hour=17, tm_min=54, tm_sec=0, tm_wday=1, tm_yday=276, tm_isdst=-1)
字符串转时间格式对应表
转换关系图
datetime模块
相比于time模块,datetime模块的接口则更直观、更容易调用
datetime模块定义了下面这几个类:
-
datetime.date:表示日期的类。常用的属性有year, month, day;
-
datetime.time:表示时间的类。常用的属性有hour, minute, second, microsecond;
-
datetime.datetime:表示日期时间。
-
datetime.timedelta:表示时间间隔,即两个时间点之间的长度。
-
datetime.tzinfo:与时区有关的相关信息。(这里不详细充分讨论该类,感兴趣的童鞋可以参考python手册)
常用方法
datetime.date.today() # 打印当前时间的年月日 只打印到日 datetime.datetime.today() # 打印当前时间的年月日 时分秒 datetime.date.timetuple() # 将日期转换为元组格式 datetime.date.ctime() # 显示英文日期格式 Fri Dec 6 00:00:00 2019 datetime.date.fromtimestamp() # 把一个时间戳转为datetime日期类型 datetime.datetime.fromtimestamp() # 将时间戳转换为datetime日期时间类型 #时间运算 >>> datetime.datetime.now() + datetime.timedelta(4) #当前时间 +4天 datetime.datetime(2017, 10, 5, 12, 53, 35, 276589) >>> datetime.datetime.now() + datetime.timedelta(hours=4) #当前时间+4小时 datetime.datetime(2017, 10, 1, 16, 53, 42, 876275) print(datetime.datetime.now()+datetime.timedelta(days=10, minutes=100, seconds=10)) # 当前时间加十天 加100分钟 加十秒 #时间替换 d = datetime.datetime.now() print(d.replace(year=2020, month=12, day=22, hour=9, minute=20, second=30)) # 将当前时间替换为2020-12-22 09:20:30.135930 >>> d.replace(year=2999,month=11,day=30) datetime.date(2999, 11, 30)
pytz # 关于时区的模块
import datetime import pytz print(datetime.datetime.now(tz=pytz.timezone(‘Asia/Dushanbe‘))) # 2019-12-06 12:07:11.573210+05:00显示时间加上时区
random随机模块
程序中有很多地方需要用到随机字符,比如登录网站的随机验证码,通过random模块可以很容易生成随机字符串
random.randrange(1,10) # 返回1到10的随机数,不包括10 random。randint(1,10) # 返回1到10的随机数,包括10 random.randrange(1,100,2) # 返回1到100的偶数 ,可指定步长 random.random() # 返回0到1的随机浮点数 random.choice(‘sde@32‘) # 返回一个给定字符集中的随机字符 random.sample(‘asd123‘,3) # 从给定字符集中选定给定数量的字符 # 生成随机字符串 import random import string a = ‘‘.join(random.sample(string.ascii_lowercase+string.digits,6)) #sring.ascii_lowercase 所有的小写英文 #string.digits 所有的数字 print(a) #洗牌 a = list(range(10)) random.shuffle(a) print(a) # 列表中的元素将打乱顺序
序列化 pickle&json模块
序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes。
用于序列化的两个模块
-
json,用于字符串 和 python数据类型间进行转换
-
pickle,用于python特有的类型 和 python的数据类型间进行转换
pickle模块提供了四个功能:dumps、dump、loads、load
import pickle d = { ‘name‘: ‘alex‘, ‘age‘: 23, ‘sex‘: ‘male‘, } a = [‘alex‘, ‘eric‘, ‘egon‘] d_dump = pickle.dumps(d) # 生成序列化的字符串 print(d_dump) # bytes类型 d_load = pickle.loads(d_dump) # 将序列化的字符串反向解析 print(d_load) f = open("pick.pkl", ‘wb‘) # f.write(d_dump) # 将序列化的二进制字符串直接写入文件 pickle.dump(d, f) # 用dump方法可以直接写入文件 pickle.dump(a, f) print(pickle.load(f)) print(pickle.load(f)) # dump几次就load几次
总结
pickle.dumps() 生成序列化的字符串
pickle.loads() 反向解析序列化的字符串
pickle.dump() 写入文件
dump几次就要load几次
写入文件时,最好只用一次dump 避免因不知道次数而引发的错误
Json模块也提供了四个功能:dumps、dump、loads、load,用法跟pickle一致
import json d = { ‘name‘: ‘alex‘, ‘age‘: 23, ‘sex‘: ‘male‘, } a = [‘alex‘, ‘eric‘, ‘egon‘] d_json = json.dumps(d) print(type(d_json)) # json.dumps() #将数据通过特殊的形式转换位所有程序语言都认识的字符串 # 注意json dumps生成的是字符串,不是bytes print(type(json.loads(d_json))) # 转换成原来的数据类型 f = open(‘js.json‘, ‘w‘) # f.write(d_json) json.dump(d, f) print(json.load(f))
总结
json 和 pickle 相似 有dump load dumps loads 四种用法
但json 和 pickle 也有不同
pickle : 支持所有python的数据类型
list、int、dict、set、str、tuple、class--object 、function 、datetime 都可以存入
但只能在python中使用 占用空间大
json: 所有语言都可以用json交接 且存入文件时体积小 便于阅读
但因为是所有语言通用的 因此只支持python常规的数据类型 int、str、list、dict、set、tuple
网站前后端的交互就是通过json传递数据 后端数据---->json序列化------>前端
一般序列化用json
hashlib模块
Hash,一般翻译做“散列”,也有直接音译为”哈希”的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。
MD5讯息摘要演算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码杂凑函数,可以产生出一个128位的散列值(hash value),用于确保信息传输完整一致。MD5的前身有MD2、MD3和MD4。
MD5功能
输入任意长度的信息,经过处理,输出为128位的信息(数字指纹);
不同的输入得到的不同的结果(唯一性);
前面我们知道hash算法可以生成一段固定的散列值,但是同一段数据,每次打开解释器hash出来的值都不相同,不能用来加密。
因此,为了进行加密 MD5算法就被发明出来 数据经过MD5算法会生成128位的散列值(一个十六进制四位)并且不管在哪一台机器上
MD5 相同的数据也是相同的。
hash算法、MD5算法,虽然生成的散列值是唯一的,但是当数据量极大时,也可能出现不同的数据,生成散列值相同的情况,称之为碰撞,但概率是极低的。
在支付宝、京东这些平台上,用户的数据就是通过加密的算法生成散列值 ,存入数据库当中。通过散列值不能倒推出明文
但是,当密码过于简单时,如果黑客得到了数据库中的密文,就可以通过穷举算法通过不断的试值进行对比 ,称之为撞库。
如果匹配上那你的信息就会泄露,
所以有些服务器为了防止撞库,就将得出的MD5值再加一些字符串 ,再进行别的运算 ,称为加盐。
常用方法
m1 = hashlib.md5() # m1.update(b"WQ2017617") # 必须是bytes类型 中文要进行encode m1.update("小猿圈".encode("utf8")) print(m1.hexdigest()) # 以16进制来显示 print(m1.hexdigest()) m2 = hashlib.sha1() # 生成160位散列值 m2.update(b"WQ2017617") print(m2.hexdigest()) m3 = hashlib.sha256() # 生成256位散列值 m3.update(b"WQ2017617") print(m3.hexdigest())
SHA-1,安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。
SHA是美国国家安全局设计的,由美国国家标准和技术研究院发布的一系列密码散列函数。
由于MD5和SHA-1于2005年被山东大学的教授王小云破解了,科学家们又推出了SHA224, SHA256, SHA384, SHA512,当然位数越长,破解难度越大,但同时生成加密的消息摘要所耗时间也更长。目前最流行的是加密算法是SHA-256 .
MD5与SHA-1的比较
由于MD5与SHA-1均是从MD4发展而来,它们的结构和强度等特性有很多相似之处,SHA-1与MD5的最大区别在于其摘要比MD5摘要长32 比特。对于强行攻击,产生任何一个报文使之摘要等于给定报文摘要的难度:MD5是2128数量级的操作,SHA-1是2160数量级的操作。产生具有相同摘要的两个报文的难度:MD5是264是数量级的操作,SHA-1 是280数量级的操作。因而,SHA-1对强行攻击的强度更大。但由于SHA-1的循环步骤比MD5多80:64且要处理的缓存大160比特:128比特,SHA-1的运行速度比MD5慢。
shutil模块
高级的 文件、文件夹、压缩包 处理模块
import shutil shutil.copyfile(‘old.py‘, ‘new.py‘) # 拷贝文件 shutil.copyfileobj(open(‘old.py‘, encoding=‘utf8‘), open(‘new_2.py‘, ‘w‘,encoding=‘utf8‘)) 将文件内容拷贝到另一个文件中 不过需要将文件打开 shutil.copymode(‘f1.log‘, ‘f2.log‘) #仅拷贝权限。内容、组、用户均不变 #目标文件必须存在 shutil.copystat(‘f1.log‘, ‘f2.log‘) # 仅拷贝状态的信息,包括:mode bits, atime, mtime, flags 目标文件必须存在 shutil.copy(‘f1.log‘, ‘f2.log‘) # 拷贝文件和权限 shutil.copytree(‘../chapter4‘, ‘new_chapter‘) # 递归地去拷贝文件夹 ..是返回上层目录 shutil.copytree(‘../chapter4‘, ‘new_chapter2‘,ignore=shutil.ignore_patterns(‘__init__.py‘,‘js*.py‘)) 拷贝文件 同时忽略某些不想要的文件 *是指所有 shutil.rmtree(‘folder1‘) # 递归的删除文件夹 shutil.move(‘new_chapter‘,‘new_chapter2/new_chapter‘) # 递归地移动文件 shutil.make_archive(base_name=‘new.zip‘,format=‘zip‘,root_dir=‘../chapter4‘) # 将文件压缩为压缩包 可选参数如下: base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径, 如 data\\_bak =>保存至当前路径 如:/tmp/data\\_bak =>保存至/tmp/ format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar” root_dir: 要压缩的文件夹路径(默认当前目录) owner: 用户,默认当前用户 group: 组,默认当前组 logger: 用于记录日志,通常是logging.Logger对象
下面做一个添加zip压缩包的代码示例
import zipfile import os # ---------------------->压缩 file_list = [] z = zipfile.ZipFile(‘new.zip.zip‘, ‘w‘) z.write(‘new.py‘) # z.write(‘new_chapter2‘) # 该方法不能写入文件夹中的文件 file = list(os.walk(‘new_chapter2‘)) # [(‘new_chapter2‘, [‘new_chapter‘, ‘__pycache__‘], [‘datetime_mod.py‘] ] # 列表中第一个元素是相对路径 第二个是文件夹 第三个该路径下的文件 # os.walk()方法会将下面的每一层的文件的路径 以及其下的文件返回 因此 可通过文件拼接的方法拿到各层文件的绝对路径 再写入压缩包 for root_dir, dirs, files in file: for i in files: file_list.append(os.path.join(root_dir, i)) for line in file_list: z.write(line) #-------------------------->解压 z = zipfile.ZipFile(‘new.zip.zip‘, ‘r‘) z.extractall(path=‘new_chapter2‘) z.close()
re模块
正则表达式就是字符串的匹配规则,在多数编程语言里都有相应的支持。
字符匹配(普通字符,元字符):
1 普通字符:大多数字符和字母都会和自身匹配
>>> re.findall(‘alvin‘,‘yuanaleSxalexwupeiqi‘)
[‘alvin‘]
2 元字符:. ^ $ * + ? { } [ ] | ( )
‘.‘ 默认匹配除 之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行 ‘^‘ 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a"," abc eee",flags=re.MULTILINE) ‘$‘ 匹配字符结尾, 若指定flags MULTILINE ,re.search(‘foo.$‘,‘foo1 foo2 ‘,re.MULTILINE).group() 会匹配到foo1 ‘*‘ 匹配*号前的字符0次或多次, re.search(‘a*‘,‘aaaabac‘) 结果‘aaaa‘ ‘+‘ 匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果[‘ab‘, ‘abb‘] ‘?‘ 匹配前一个字符1次或0次 ,re.search(‘b?‘,‘alex‘).group() 匹配b 0次
‘[]‘ 字符集 ‘{m}‘ 匹配前一个字符m次 ,re.search(‘b{3}‘,‘alexbbbs‘).group() 匹配到‘bbb‘ ‘{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|45)", "abcabca456c").group() 结果为‘abcabca45‘ ‘A‘ 只从字符开头匹配,re.search("Aabc","alexabc") 是匹配不到的,相当于re.match(‘abc‘,"alexabc") 或^ ‘‘ 匹配字符结尾,同$ ‘d‘ 匹配数字0-9 ‘D‘ 匹配非数字 ‘w‘ 匹配[A-Za-z0-9] ‘W‘ 匹配非[A-Za-z0-9] ‘s‘ 匹配空白字符、 、 、 , re.search("s+","ab c1 3").group() 结果 ‘ ‘ ‘(?P...)‘ 分组匹配 re.search("(?P[0-9]{4})(?P[0-9]{2})(?P[0-9]{4}
re的匹配语法有以下几种
-
re.match 从头开始匹配
-
re.search 匹配包含
-
re.findall 把所有匹配到的字符放到以列表中的元素返回
-
re.split 以匹配到的字符当做列表分隔符
-
re.sub 匹配字符并替换
-
re.fullmatch 全部匹配
import re ret=re.findall(‘a..in‘,‘helloalvin‘) print(ret)#[‘alvin‘] ret=re.findall(‘^a...n‘,‘alvinhelloawwwn‘) print(ret)#[‘alvin‘] ret=re.findall(‘a...n$‘,‘alvinhelloawwwn‘) print(ret)#[‘awwwn‘] ret=re.findall(‘a...n$‘,‘alvinhelloawwwn‘) print(ret)#[‘awwwn‘] ret=re.findall(‘abc*‘,‘abcccc‘)#贪婪匹配[0,+oo] print(ret)#[‘abcccc‘] ret=re.findall(‘abc+‘,‘abccc‘)#[1,+oo] print(ret)#[‘abccc‘] ret=re.findall(‘abc?‘,‘abccc‘)#[0,1] print(ret)#[‘abc‘] ret=re.findall(‘abc{1,4}‘,‘abccc‘) print(ret)#[‘abccc‘] 贪婪匹配
注意:前面的*,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配
ret=re.findall(‘abc*?‘,‘abcccccc‘) print(ret)#[‘ab‘]
字符集[ ]
ret=re.findall(‘a[bc]d‘,‘acd‘) print(ret)#[‘acd‘] ret=re.findall(‘[a-z]‘,‘acd‘) print(ret)#[‘a‘, ‘c‘, ‘d‘] ret=re.findall(‘[.*+]‘,‘a.cd+‘) print(ret)#[‘.‘, ‘+‘] #在字符集里有功能的符号: - ^ # ^ 在字符集中是取反的功能 ret=re.findall(‘[1-9]‘,‘45dha3‘) print(ret)#[‘4‘, ‘5‘, ‘3‘] ret=re.findall(‘[^ab]‘,‘45bdha3‘) # 匹配除ab外的所有字符 print(ret)#[‘4‘, ‘5‘, ‘d‘, ‘h‘, ‘3‘] ret=re.findall(‘[d]‘,‘45bdha3‘) print(ret)#[‘4‘, ‘5‘, ‘3‘]
元字符之转义符
反斜杠后边跟元字符去除特殊功能,比如.
反斜杠后边跟普通字符实现特殊功能,比如d
d 匹配任何十进制数;它相当于类 [0-9]。
D 匹配任何非数字字符;它相当于类 [^0-9]。
s 匹配任何空白字符;它相当于类 [
fv]。
S 匹配任何非空白字符;它相当于类 [^
fv]。
w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]
匹配一个特殊字符边界,比如空格 ,&,#等
import re ret=re.findall(‘cl‘,‘abcle‘) print(ret)#[] ret=re.findall(‘cl‘,‘abcle‘) print(ret)#[] ret=re.findall(‘c\\l‘,‘abcle‘) print(ret)#[‘cl‘] ret=re.findall(r‘cl‘,‘abcle‘) print(ret)#[‘cl‘] #之所以选择是因为在ASCII表中是有意义的 m = re.findall(‘blow‘, ‘blow‘) print(m) m = re.findall(r‘blow‘, ‘blow‘) print(m)
元字符之分组()
m = re.findall(r‘(ad)+‘, ‘add‘) print(m) ret=re.search(‘(?P<id>d{2})/(?P<name>w{3})‘,‘23/com‘) print(ret.group())#23/com print(ret.group(‘id‘))#23
元字符之|
ret=re.search(‘(ab)|d‘,‘rabhdg8sd‘) print(ret.group())#ab
re模块下的常用方法
import re #1 re.findall(‘a‘,‘alvin yuan‘) #返回所有满足匹配条件的结果,放在列表里 #2 re.search(‘a‘,‘alvin yuan‘).group() #函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以 # 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。 #3 re.match(‘a‘,‘abc‘).group() #同search,不过尽在字符串开始处进行匹配 #4 ret=re.split(‘[ab]‘,‘abcd‘) #先按‘a‘分割得到‘‘和‘bcd‘,在对‘‘和‘bcd‘分别按‘b‘分割 print(ret)#[‘‘, ‘‘, ‘cd‘] #5 ret=re.sub(‘d‘,‘abc‘,‘alvin5yuan6‘,1) print(ret)#alvinabcyuan6 ret=re.subn(‘d‘,‘abc‘,‘alvin5yuan6‘) print(ret)#(‘alvinabcyuanabc‘, 2) #6 obj=re.compile(‘d{3}‘) ret=obj.search(‘abc123eeee‘) print(ret.group())#123 import re ret=re.finditer(‘d‘,‘ds3sy4784a‘) print(ret) #<callable_iterator object at 0x10195f940> print(next(ret).group()) print(next(ret).group())
注意
import re ret=re.findall(‘www.(baidu|oldboy).com‘,‘www.oldboy.com‘) print(ret)#[‘oldboy‘] 这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可 ret=re.findall(‘www.(?:baidu|oldboy).com‘,‘www.oldboy.com‘) print(ret)#[‘www.oldboy.com‘]
补充:
import re print(re.findall("<(?P<tag_name>w+)>w+</(?P=tag_name)>","<h1>hello</h1>")) a = re.search("<(?P<tag_name>w+)>w+</(?P=tag_name)>","<h1>hello</h1>") print(a.groups()) # 将匹配到的以元组形式打印 print(a.groupdict()) # 将匹配到的以字典形式打印出 tag_name: xxx #匹配出所有的整数 import re #ret=re.findall(r"d+{0}]","1-2*(60+(-40.35/5)-(-4*3))") ret=re.findall(r"-?d+.d*|(-?d+)","1-2*(60+(-40.35/5)-(-4*3))") ret.remove("") print(ret)
compile and match
re.compile(pattern, flags=0) Compile a regular expression pattern into a regular expression object, which can be used for matching using its match(), search() and other methods, described below. The sequence prog = re.compile(pattern) result = prog.match(string) is equivalent to result = re.match(pattern, string) but using re.compile() and saving the resulting regular expression object for reuse is more efficient when the expression will be used several times in a single program. # 普通的匹配是每一次都找规则 再去匹配字符 # compile 先找出对应规则 再一次性匹配出字符 re.match(pattern, string, flags=0) 从起始位置开始根据模型去字符串中匹配指定内容,匹配单个 pattern 正则表达式 string 要匹配的字符串 flags 标志位,用于控制正则表达式的匹配方式 import re obj = re.match(‘d+‘, ‘123uuasf‘) #如果能匹配到就返回一个可调用的对象,否则返回None if obj: print obj.group()
Flag标志符
Flags标志符 re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同) re.M(MULTILINE): 多行模式,改变’^’和’$’的行为 re.S(DOTALL): 改变’.’的行为,make the ‘.’ special character match any character at all, including a newline; without this flag, ‘.’ will match anything except a newline. re.X(re.VERBOSE) 可以给你的表达式写注释,使其更可读,下面这2个意思一样 a = re.compile(r"""d + # the integral part . # the decimal point d * # some fractional digits""", re.X) b = re.compile(r"d+.d*") re.search(pattern, string, flags=0) 根据模型去字符串中匹配指定内容,匹配单个 import re obj = re.search(‘d+‘, ‘u123uu888asf‘) if obj: print obj.group() re.findall(pattern, string, flags=0) match and search均用于匹配单值,即:只能匹配字符串中的一个,如果想要匹配到字符串中所有符合条件的元素,则需要使用 findall。 import re obj = re.findall(‘d+‘, ‘fa123uu888asf‘) print obj re.sub(pattern, repl, string, count=0, flags=0) 用于替换匹配的字符串,比str.replace功能更加强大 >>>re.sub(‘[a-z]+‘,‘sb‘,‘武配齐是abc123‘,) >>> re.sub(‘d+‘,‘|‘, ‘alex22wupeiqi33oldboy55‘,count=2) ‘alex|wupeiqi|oldboy55‘ re.split(pattern, string, maxsplit=0, flags=0) 用匹配到的值做为分割点,把值分割成列表 >>>s=‘9-2*5/3+7/3*99/4*2998+10*568/14‘ >>>re.split(‘[*-/+]‘,s) [‘9‘, ‘2‘, ‘5‘, ‘3‘, ‘7‘, ‘3‘, ‘99‘, ‘4‘, ‘2998‘, ‘10‘, ‘568‘, ‘14‘] >>> re.split(‘[*-/+]‘,s,3) [‘9‘, ‘2‘, ‘5‘, ‘3+7/3*99/4*2998+10*568/14‘] re.fullmatch(pattern, string, flags=0) 整个字符串匹配成功就返回re object, 否则返回None re.fullmatch(‘w+@w+.(com|cn|edu)‘,"alex@oldboyedu.cn")
注:部分参考自路飞学城及银角大王博客。
以上是关于常用模块的主要内容,如果未能解决你的问题,请参考以下文章