模块
常用模块一
时间模块
random模块
os模块
sys模块
序列化模块
re模块
常用模块二
hashlib模块
configparse模块
logging模块
什么是模块?
常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀。
但其实import加载的模块分为四个通用类别:
1 使用python编写的代码(.py文件)
2 已被编译为共享库或DLL的C或C++扩展
3 包好一组模块的包
4 使用C编写并链接到python解释器的内置模块
使用模块的原因?
如果你退出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行,此时test.py被称为脚本script。
随着程序的发展,功能越来越多,为了方便管理,我们通常将程序分成一个个的文件,这样做程序的结构更清晰,方便管理。这时我们不仅仅可以把这些文件当做脚本去执行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用,
常用模块
1、collections模块
在内置函数类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:counter、deque、defaultdict。namedtuple和ordereddict等。
1、namedtuple:生成可以使用名字来访问元素内容的tuple
2、deque:双端队列,可以快速的从另外一侧追加和推出对象
3、counter:计数器,主要用来计数
4、defaultdict:带有默认值的字典
namedtuple
tuple可以表示不变集合,例如,一个点的二维坐标可以表示成
p=(1,2)
但是看到(1,2)很难看出它是一个坐标的,此时,就可以使用namedtuple
from collections import namedtuple point=namedtuple('point',['x','y']) p=point(1,2) print(p.x) # 1 print(p.y) # 2
同样的,如果要用坐标和半径表示一个圆,也可用namedtuple来定义:
from collections import namedtuple circle=namedtuple('circle',['x','y','r']) print(circle)
deque
使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
from collections import deque q=deque(['a','b','c']) q.append('x') q.append('y') print(q) # deque(['a', 'b', 'c', 'x', 'y'])
deque除了实现list的append()
和pop()
外,还支持appendleft()
和popleft()
,这样就可以非常高效地往头部添加或删除元素。
OrderedDict
使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
如果要保持Key的顺序,可以用OrderedDict
:
from collections import _OrderedDictItemsView d=dict([('a',1),('b',2),('c',3)]) print(d) # {'a': 1, 'b': 2, 'c': 3} od=_OrderedDictItemsView([('a',1),('b',2),('c',3)]) print(od) # _OrderedDictItemsView([('a', 1), ('b', 2), ('c', 3)])
注意,OrderedDict
的Key会按照插入的顺序排列,不是Key本身排序。
defaultdict
有如下值集合 [
11
,
22
,
33
,
44
,
55
,
66
,
77
,
88
,
99
,
90.
..],将所有大于
66
的值保存至字典的第一个key中,将小于
66
的值保存至第二个key的值中。即:{'k1':大于66,'k2':小于66}
values = [11, 22, 33,44,55,66,77,88,99,90] my_dict = {} for value in values: if value>66: if ['k1'] in values: my_dict['k1'].append(value) else: my_dict['k1'] = value else: if ['k2'] in values: my_dict['k2'].append(value) else: my_dict['k2'] = value print(my_dict)
defaultdict字典解决方法:
from collections import defaultdict values = [11, 22, 33,44,55,66,77,88,99,90] my_dict = defaultdict(list) for value in values: if value > 66: my_dict['k1'].append(value) else: my_dict['k2'].append(value) print(my_dict) # defaultdict(<class 'list'>, {'k2': [11, 22, 33, 44, 55, 66], 'k1': [77, 88, 99, 90]})
使用dict
时,如果引用的Key不存在,就会抛出KeyError
。如果希望key不存在时,返回一个默认值,就可以用defaultdict
:
from collections import defaultdict dd=defaultdict(lambda : 'N/A') dd['key1']='abc' print(dd['key1']) # abc print(dd['key2']) # N/A
conter:conter类的目的是用来跟踪值出现的次数。是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数为value。计数值可以是任意的interger(包括0和负数)。
from collections import Counter c=Counter('sjkhshddheuiskj') print(c) # Counter({'s': 3, 'h': 3, 'j': 2, 'k': 2, 'd': 2, 'e': 1, 'u': 1, 'i': 1})
时间模块
表示时间的三种方式:
在Python中,通常有三种方式来表示时间:时间戳、元组(struct_time)、格式化的时间字符串
1)时间戳(timestamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。在运行“type(time.time())”,返回的是float类型。
2)格式化的时间字符串(Format String):'1999-12-06'
%y 两位数的年份表示(00-99) %Y 四位数的年份表示(000-9999) %m 月份(01-12) %d 月内中的一天(0-31) %H 24小时制小时数(0-23) %I 12小时制小时数(01-12) %M 分钟数(00=59) %S 秒(00-59) %a 本地简化星期名称 %A 本地完整星期名称 %b 本地简化的月份名称 %B 本地完整的月份名称 %c 本地相应的日期表示和时间表示 %j 年内的一天(001-366) %p 本地A.M.或P.M.的等价符 %U 一年中的星期数(00-53)星期天为星期的开始 %w 星期(0-6),星期天为星期的开始 %W 一年中的星期数(00-53)星期一为星期的开始 %x 本地相应的日期表示 %X 本地相应的时间表示 %Z 当前时区的名称 %% %号本身
3)元组(struct_time):sruct_time元组共有9个元素(年、月、日、时、分、秒、一年中第几周、一年中第几天等)
索引(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-60 |
6 | tm_wday(weekday) | 0-6(其中0表示周一) |
7 | tm_yday(一年中的第几天) | 1-366 |
8 | tm_isdst(是否是夏令时) | 默认为0 |
首先,导入time模块,认识一下python中表示时间的几种格式:
import time # 导入时间模块 print(time.time()) # 时间戳 1510650648.867422 print(time.strftime('%Y-%m-%d %X')) # 时间字符串 2017-11-14 17:12:06 print(time.strftime('%Y-%m-%d %H-%M-%S')) # 时间字符串 2017-11-14 17-13-06 # 时间元组:localtime将一个时间戳转换为当前时区的struct_time print(time.localtime()) # time.struct_time(tm_year=2017, tm_mon=11, tm_mday=14, tm_hour=18, tm_min=42, tm_sec=45, tm_wday=1, tm_yday=318, tm_isdst=0)
小结:时间戳是计算机能够识别的时间;时间字符串是人能够看懂的时间;元组则是用来操作时间的。
几种格式之间的转换:
时间戳---->结构化时间
# time.gmtime(时间戳) #UTC时间,与英国伦敦当地时间一致 # time.localtime(时间戳) #当地时间。例如我们现在在北京执行这个方法:与UTC时间相差8小时,UTC时间+8小时 = 北京时间 import time print(time.gmtime(150000000)) # time.struct_time(tm_year=1974, tm_mon=10, tm_mday=3, tm_hour=2, tm_min=40, tm_sec=0, tm_wday=3, tm_yday=276, tm_isdst=0) print(time.localtime(1500000000)) # time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=10, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0)
结构化时间---->时间戳
# time.mktime(结构化时间) import time time_tuple=time.localtime(16999999) time=time.mktime(time_tuple) print(time) # 16999999.0
结构化时间---->字符串时间
# time.strftime("格式定义","结构化时间") 结构化时间参数若不传,则显示当前时间 import time print(time.strftime('%Y-%m-%d %X')) # 2017-11-14 18:51:41 print(time.strftime('%Y-%m-%d',time.localtime(1699999))) # 1970-01-21
字符串时间---->结构化时间
# time.strptime(时间字符串,字符串对应格式) import time print(time.strptime('2017-03-16','%Y-%m-%d')) # time.struct_time(tm_year=2017, tm_mon=3, tm_mday=16, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=75, tm_isdst=-1) print(time.strptime('07-24-2017','%m-%d-%Y')) # time.struct_time(tm_year=2017, tm_mon=7, tm_mday=24, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=205, tm_isdst=-1)
结构化时间---->%a %b %d %H:%M:%S %Y串
#time.acstime(结构化时间) 如果不传参数,直接返回当前时间的格式化串 import time print(time.asctime(time.localtime(1500000000))) # Fri Jul 14 10:40:00 2017 print(time.asctime()) # Tue Nov 14 19:12:21 2017
%a %b %d %H:%M:%S %Y串----->结构化时间
# time.ctime(时间戳) 如果不传参数,直接返回当前时间的格式化串 import time print(time.ctime()) # Tue Nov 14 19:16:45 2017 print(time.ctime(1599999999)) # Sun Sep 13 20:26:39 2020
计算时间差:
import time old_time=time.mktime(time.strptime('2017-09-11 08:35:45','%Y-%m-%d %H:%M:%S')) now_time=time.mktime(time.strptime('2017-9-12 23:00:32','%Y-%m-%d %H:%M:%S')) dif_time=now_time-old_time struct_time=time.gmtime(dif_time) print('过去了%d年%d月%d天%d小时%d分钟%d秒'%(struct_time.tm_year-1970,struct_time.tm_mon-1, struct_time.tm_mday-1,struct_time.tm_hour,struct_time.tm_min,struct_time.tm_sec)) # 过去了0年0月1天14小时24分钟47秒
random:
1、随机小数
import random print(random.random()) # 随机输出0—1之间的小数 # 0.34589021676563914 print(random.uniform(1,2)) # 随机输出1-2之间的小数 # 1.7413432475715864
2、随机整数
print(random.randint(1,5)) # 随机输出1-5之间的整数,包含1和5 print(random.randrange(1,5)) # 随机输出1-5之间的整数,包含1但不包含5
3、随机选择一个返回
print(random.choice([1,'23',[4,5],{6,7},{'k','v'}]))
4、随机选择多个返回,返回的个数为函数的第二个参数
print(random.sample([1,'23',[4,5],{6,7},{'k','v'}],3)) # [1, '23', {6, 7}]
5、打乱列表顺序
l=[1,'23',[4,5],{6,7},{'k','v'}] random.shuffle(l) print(l) # ['23', {'k', 'v'}, {6, 7}, 1, [4, 5]]
练习:验证码
import random def v_code(): code='' for i in range(5): num=random.randint(0,9) alf=chr(random.randint(65,90)) add=random.choice([num,alf]) code=''.join([code,str(add)]) return code print(v_code()) # 82M83 随机产生的6位由数字和字母组成的验证码
os模块:os模块是与操作系统交互的一个接口
''' os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd os.curdir 返回当前目录: ('.') os.pardir 获取当前目录的父目录字符串名:('..') os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 os.remove() 删除一个文件 os.rename("oldname","newname") 重命名文件/目录 os.stat('path/filename') 获取文件/目录信息 os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/" os.linesep 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n" os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为: os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix' os.system("bash command") 运行shell命令,直接显示 os.popen("bash command) 运行shell命令,获取执行结果 os.environ 获取系统环境变量 os.path 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所指向的文件或者目录的最后修改时间 os.path.getsize(path) 返回path的大小 '''
注意:os.stat('path/filename')获取文件/目录信息的结构说明
stat 结构: st_mode: inode 保护模式 st_ino: inode 节点号。 st_dev: inode 驻留的设备。 st_nlink: inode 的链接数。 st_uid: 所有者的用户ID。 st_gid: 所有者的组ID。 st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。 st_atime: 上次访问的时间。 st_mtime: 最后一次修改的时间。 st_ctime: 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间(详细信息参见平台的文档)。
sys模块:
sys模块是与python解释器交互的一个接口
序列化方法:json
序列化方法是专门做格式化转换的。是把python中的数据转换成str叫做序列化;将str转换成python中的数据叫做反序列化。
1、json:是所有语言都通用的,能序列化的数据类型有限,只有:字典、列表、元组三种。序列化的内容只能包含:字典、列表、数字、字符串。
import json ret = json.dumps({'k':(1,2,3)}) print(repr(ret),type(ret)) # '{"k": [1, 2, 3]}' <class 'str'> ret=json.dumps([1,2,3]) print(repr(ret),type(ret)) # '[1, 2, 3]' <class 'str'> # 直接使用json会将dumps的内容变成字符串
2、loads:反序列化,将ste转换成python中的数据
3、dumps:序列化,将一个python数据类型转换成一个字符串。
import json ret = json.dumps({'k': (1, 2, 3)}) ret1 = json.loads(ret) # loads(ret)将ret中的value变成了列表 print(repr(ret1), type(ret1)) # {'k': [1, 2, 3]} <class 'dict'> ret3 = json.dumps([1, 2, 3]) ret2 = json.loads(ret3) #注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示
print(repr(ret2), type(ret2)) # [1, 2, 3] <class 'list'> # 使用json将由dumps得到的python数据类型转换成字符串,这种叫序列化
# 使用loads之后又将字符串还原成原来的数据类型,这种叫反序列化
4、dump:dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件。
import json f = open('json_file','w') json.dump({'k':(1,2,3)},f) # dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件 f.close() with open('json_file') as f: ret = json.load(f) print(ret, type(ret))
f = open('json_file')
dic2 = json.load(f) #load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
f.close()
print(type(dic2),dic2)
5、pickle:可以序列化任何数据类型,python专有的,不能和其他语言兼容,结果是bytes类型。
import pickle # 用pickle序列化的数据,反序列化也必须使用pickle ret = pickle.dumps({1,2,3,4}) print(ret) #b'\x80\x03cbuiltins\nset\nq\x00]q\x01(K\x01K\x02K\x03K\x04e\x85q\x02Rq\x03.'
shelve:只提供一个open,shelve.open('文件名')拿到一个文件句柄,这个文件句柄就可以当作字典操作。
正则表达式:
字符组 : [字符组] 在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示 字符分为很多类,比如数字、字母、标点等等。 假如你现在要求一个位置"只能出现一个数字",那么这个位置上的字符只能是0、1、2...9这10个数之一。
正则 | 待匹配字符 | 匹配结果 | 说明 |
[0123456789] | 8 | True | 在一个字符组里枚举合法的所有字符,字符组里的任意一个字符和"待匹配字符"相同都视为可以匹配 |
[0123456789] | a | False | 由于字符组中没有"a"字符,所以不能匹配 |
[0-9] | 7 | True | 也可以用"-"来表示范围,[0-9]就和[0123456789]是一个意思 |
[a-z] | s | True | 同样的要匹配所有的小写字母,直接用[a-z]就可以表示 |
[A-Z] | B | True | [A-Z]就表示所有的大写字母 |
[0-9a-fA-F] | e | True | 可以匹配数字,大小写形式的a-f,用来验证十六进制字符 |
字符:
元字符 | 匹配内容 |
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线 是word的简写 |
\s | 匹配任意的空白符 是space的简写 |
\d | 匹配数字 是digit的简写 |
\n | 匹配一个换行符 是next的简写 |
\t | 匹配一个制表符 是table的简写 |
\b | 匹配一个单词的结尾 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结尾 |
\W | 匹配非字母或数字或下划线 |
\D | 匹配非数字 |
\S | 匹配非空白符 |
a|b | 匹配字符a或字符b,先匹配a,若a匹配成功,则不再匹配b;若匹配不成功,则再匹配b |
() | 匹配括号内的表达式,也表示一个组 |
[...] | 匹配字符组中的字符 |
[^...] | 匹配除了字符组中的所有字符 |
量词:
量词 | 用法说明 |
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
.^$
正则 | 待匹配字符 | 匹配结果 | 说明 |
海.(.是匹配除换行符以外的任意字符,只要有符合条件的就会进行匹配,一共得到3个匹配结果) | 海燕海娇海东 | 海燕海娇海东 | 匹配所有"海"的字符 |
^海.(^从头开始匹配,且只匹配以"海"开头的,一共得到1个匹配结果) | 海燕海娇海东 | 海燕 | 只从开头匹配"海" |
海.$(匹配一"海."结尾的,一共得到1个匹配结果) | 海燕海娇海东 | 海东 | 只匹配结尾的"海" |
* + ? { }
正则 | 待匹配字符 | 匹配结果 | 说明 |
李.? |
李杰和李莲英和李二棍子 |
李杰 李莲 李二 |
?表示重复零次或一次,即只匹配"李"后面的任意一个字符,匹配到3条结果 |
李.* | 李杰和李莲英和李二棍子 | 李杰和李莲英和李二棍子 | *表示重复零次或多次,即匹配"李"后面0个或多个任意字符,匹配到1条结果 |
李.+ | 李杰和李莲英和李二棍子 | 李杰和李莲英和李二棍子 | +表示重复一次或多次,即只匹配"李"后面1个或多个任意字符,匹配到1条结果 |
李.{1,2} | 李杰和李莲英和李二棍子 |
李杰和 李莲英 李二棍 |
{1,2}匹配1到2次任意字符匹配到3条结果 |
注意:前面的*,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配
正则 | 待匹配字符 | 匹配结果 | 说明 |
李.*? | 李杰和李莲英和李二棍子 |
李 李 李 |
惰性匹配 |
字符集[ ] [^]
正则 | 待匹配字符 | 匹配结果 | 说明 |
李[杰莲英二棍子]* | 李杰和李莲英和李二棍子 |
李杰 李莲英 李二棍子 |
表示匹配"李"字后面[杰莲英二棍子]的字符任意次,匹配到3个结果 |
李[^和]* | 李杰和李莲英和李二棍子 |
李杰 |
表示匹配一个不是"和"的字符任意次 |
[\d] |
456bdha3 |
4 5 6 3 |
表示匹配任意一个数字,匹配到4个结果 |
[\d]+ |
456bdha3 |
456 3 |
表示匹配任意个数字,匹配到2个结果 |
分组 ()与 或 |[^]
正则 | 待匹配字符 | 匹配结果 | 说明 |
^[1-9]\d{13,16}[0-9x]$ | 110101198001017032 | 110101198001017032 | 表示可以匹配一个正确的身份证号 |
^[1-9]\d{13,16}[0-9x]$ | 1101011980010170 | 1101011980010170 | 表示也可以匹配这串数字,但这并不是一个正确的身份证号码,它是一个16位的数字 |
^[1-9]\d{14}(\d{2}[0-9x])?$ | 1101011980010170 | False | 现在不会匹配错误的身份证号了,()表示分组,将\d{2}[0-9x]分成一个组,就可以整体约束他们出现的次数为0-1次 |
^([1-9]\d{16}[0-9x]|[1-9]\d{14})$ | 110105199812067023 | 110105199812067023 | 表示先匹配[1-9]\d{16}[0-9x]如果没有匹配上就匹配[1-9]\d{14} |
转义符\:
在正则表达式中,有很多有特殊意义的是元字符,比如\d和\s等,如果要在正则中匹配正常的"\d"而不是"数字"就需要对"\"进行转义,变成"\\"
在python中,无论是正则表达式,还是待匹配的内容,都是以字符串的形式出现的,在字符串中\也有特殊的含义,本身还需要转义。所以如果匹配一次"\d",字符串中要写成'\\d',那么正则里就要写成"\\\\d",这样就太麻烦了。这个时候我们就用到了r'\d'这个概念,此时的正则是r'\\d'就可以了。
正则 | 待匹配字符 | 匹配结果 | 说明 |
\d | \d | False | 因为这正则表达式中\是有特殊意义的字符,所以更要匹配\d本身,用表达式\d无法匹配 |
\\d | \d | True | 转义\之后变成\\,即可匹配 |
"\\\\d" | '\\d' | True | 如果在python中,字符串中的'\'也需要转义,所以每一个字符串'\'又需要转义一次 |
r'\\d' | r'\d' | True | 在字符串之前加r,让整个字符串不转义 |
贪婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配。
正则 | 待匹配字符 | 匹配结果 | 说明 |
<.*> | <script>...<script> | <script>...<script> | 默认为贪婪匹配模式,会匹配尽量长的字符串 |
<.*?> | r'\d' |
<script> <script> |
加上?为将贪婪匹配模式转为非贪婪匹配模式,会匹配尽可能段的字符串 |
几个常用的非贪婪匹配pattern
*?重复任意次,但尽可能少重复 +?重复1次或更多次,但尽可能少重复 ??重复0次或1次,但尽可能少重复 {n,m}?重复n到m次,但尽可能少重复 {n,}?重复n次以上,但尽可能少重复
.*?的用法
.是任意字符 *是取0至无限长度 ?是非贪婪模式 合在一起就是取尽量少的任意字符,一般不会这么单独写,大多用在:.*?x(即,取前面任意长度的字符,直到一个x出现)
re模块下的常用方法:
1、findall:将所有满足匹配条件的结果返回,并放在列表中
import re ret=re.findall('a','eva egon yuan') print(ret) # ['a', 'a']
2、search:函数会在字符串内查找模式匹配,只要找到第一个匹配之后就会返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
import re ret=re.search('a','eva egon yuan').group() print(ret) # a
3、match:同search,不过仅在字符串开始处进行匹配
import re ret=re.match('a','eva egon yuan').group() print(ret) #结果报错,这是因为match是从头开始匹配的,在eva egon yuan中不是以a为开头的,所以会报错 ret=re.match('a','abc').group() print(ret) # a
4、split:('被切割的原则','字符串')
import re ret=re.split('[ab]','abc') print(ret) # ['', '', 'c'] ret=re.split('[b]','abc') print(ret) # ['a', 'c']
5、sub:('替换的字符','待替换的字符','原字符串')输出的是替换后的字符串。
import re ret=re.sub('\d','H','1h3w3') print(ret) # HhHwH ret=re.sub('h','H','1h3w3') print(ret) # 1H3w3
6、subn:('替换的字符','待替换的字符','原字符串') 输出的是替换后的字符串,而且还会返回替换的次数。
import re ret=re.subn('c','_sb','axlic wusirc ritianc') print(ret) # ('axli_sb wusir_sb ritian_sb', 3)
7、compile:
import re joc=re.compile('\d{3}')# 将正则表达式编译成为一个正则表达式对象,规则是:匹配3个数字 print(joc) # re.compile('\\d{3}') ret=joc.search('abc123edsk345').group() # 对正则表达式对象用search,参数为待匹配的字符串 print(ret) # 123
8、finditer:
import re ret=re.finditer('\d','sh2hkhk3h899sjhj') # finditer返回一个存放匹配结果的迭代器 print(ret) # <callable_iterator object at 0x0000017202D01630> print(next(ret).group()) # 2 查看第一个数字 print(next(ret).group()) # 3 查看第二个数字 print([i.group() for i in ret]) # ['8','9','9'] 查看剩余的数字
注意:
1、findall的优先级查询:
import re ret=re.findall('www.(baidu|oldoy).com','www.baidu.com') print(ret) # ['baidu'] # 这是因为这正则表达式www.(baidu|oldoy).com中,baidu|oldby是用()括起来的,括号里的优先级比其他的要高,所以findall将优先匹配结果返回,如果想要匹配结果,取消权限即可 ret=re.findall('www.(?:baidu|oldoy).com','www.baidu.com') print(ret) # ['www.baidu.com']
2、split的优先级查询
import re ret=re.split('\d','whjh345hu67j6hj') print(ret) # ['whjh', '', '', 'hu', '', 'j', 'hj'] ret=re.split('\d','whjh5hu7j6hj') print(ret) # ['whjh', 'hu', 'j', 'hj'] 以数字为分割的标准,分割之后将数字去掉了 ret=re.split('(\d+)','whjh5hu7j6hj') print(ret) # ['whjh', '5', 'hu', '7', 'j', '6', 'hj'] 同样的以数字为分割的标准,但是正则表达式是(\d+),切割之后数字依然保留且成为列表中的一个元素 # 在匹配部分加上()之后切出的结果是不同的 # 没有()的没有保留所匹配的项,但是有()的却能够保留匹配的项