模块

常用模块一

  时间模块

  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+),切割之后数字依然保留且成为列表中的一个元素

# 在匹配部分加上()之后切出的结果是不同的
# 没有()的没有保留所匹配的项,但是有()的却能够保留匹配的项

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2017-11-13 17:33  卖火柴的嫩火柴  阅读(194)  评论(0编辑  收藏  举报

导航