python 模块
1 time模块
在python中,通常有三种表示时间的方式:时间戳、格式化时间字符串、结构化时间。
1 时间的表示方式
- 时间戳
通常来说,时间戳表示的是从1970年1月1日08:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。为什么要有这样一种表示法呢?因为计算机不像人,有“年月日”的概念,这样一种秒的表示法,是为了给计算机来读。
print(time.time()) #结果:1493622474.759625
- 格式化时间字符串(Format String)
是为了给人看的
print(time.strftime("%Y-%m-%d %X")) #结果:2017-05-01 15:14:03
- 结构化时间(struct_time)
用来对时间进行操作
struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等)
print(time.localtime()) #默认的参数是当前的时间戳
t=time.localtime()
print(t.tm_year,t.tm_mon,t.tm_mday)
结果:
time.struct_time(tm_year=2017, tm_mon=5, tm_mday=1, tm_hour=15, tm_min=17, tm_sec=18, tm_wday=0, tm_yday=121, tm_isdst=0)
2017 5 1
- 其他
print(time.clock()) #以浮点数计算的秒数返回当前的CPU时间
#用于测试程序运行时间
2 几种时间的形式转换
先讲讲localtime和gmtime的区别:
print(time.localtime())
print(time.gmtime())
结果:
time.struct_time(tm_year=2017, tm_mon=5, tm_mday=1, tm_hour=15, tm_min=27, tm_sec=1, tm_wday=0, tm_yday=121, tm_isdst=0)
time.struct_time(tm_year=2017, tm_mon=5, tm_mday=1, tm_hour=7, tm_min=27, tm_sec=1, tm_wday=0, tm_yday=121, tm_isdst=0)
他们都是结构化时间的表示法,但两者相差8个小时。
time.localtime()获取的是当前地区时间(东8区,北京时间) (推荐)
time.gmtime()获取的是世界标准时间(格林尼治时间)
#时间戳->结构化时间
print(time.localtime(3600*24)) #time.struct_time(tm_year=1970, tm_mon=1, tm_mday=2, tm_hour=8, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=2, tm_isdst=0)
#时间戳<-结构化时间
print(time.mktime(time.localtime())) #1493624339.0
#结构化时间->格式化时间
print(time.strftime("%Y-%m-%d %X",time.localtime())) #2017-05-01 15:40:46
#结构化时间<-格式化时间
print(time.strptime("2017-03-30","%Y-%m-%d")) #time.struct_time(tm_year=2017, tm_mon=3, tm_mday=30, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=89, tm_isdst=-1)
#结构化时间和时间戳->格式化时间
print(time.ctime(time.time())) #Mon May 1 15:50:25 2017
print(time.asctime(time.localtime())) #Mon May 1 15:50:25 2017
2 random模块
import random
print(random.random()) #大于0小于1的小数
print(random.randint(1,3)) #大于等于1小于等于3的小数
print(random.randrange(1,3)) #大于等于1小于3的小数
print(random.choice([1,3,5,7])) #从序列随机选取一个
#3
print(random.sample([1,2,3,4,5],2)) #从序列随机选取2个
#[2, 3]
print(random.uniform(1,3)) #大于1小于3的小数
#1.66606716724746
li=[1,2,3,4,5]
random.shuffle(li) #随机将顺序打乱
print(li)
#[1, 5, 4, 2, 3]
练习:生成验证码
#随机生成5个a-z A-Z 0-9的数
import random
def v_code():
code=""
for i in range(5):
r1= random.randint(0,9)
r2=chr(random.randint(97,122))
r3=chr(random.randint(65,90))
r=random.choice([str(r1),r2,r3])
code+=r
print(code)
v_code() #cp8rX
3 hashlib
python的hashlib提供的常用摘要算法,如MD5,SHA1等。
什么是摘要算法呢?摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的bytes数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。
摘要算法是通过摘要函数对任意长度的bytes数据data计算出规定长度的摘要digest,目的是为了检查原始数据是否被人篡改过。
摘要算法之所以能指出数据是否被篡改过,就是因为摘要函数是一个单向函数,计算f(data)很容易,但通过digest反推data却非常困难。而且,对原始数据做一个bit的修改,都会导致计算出的摘要完全不同。
以常见的摘要算法MD5为例,计算出一个字符串的MD5值:
import hashlib
m5=hashlib.md5()
m5.update("egg".encode("utf-8"))
print(m5.hexdigest())
#结果:0e9312087f58f367d001ec9bae8f325a
如果数据量巨大,可以分块多次调用update():
l=hashlib.md5()
l.update(b"110")
l.update(b"egg")
#可以合并着写,结果一样:l.update(b"110egg")
print(l.hexdigest())
#5a680543e062ec341ecf6b0047246a80
用于常用的口令的MD5很容易被计算出来。所以,在存储用户口令时,会对原始口令加一个复杂字符串来实现,俗称“加盐”:
m=hashlib.md5(b"110") #加盐
m.update(b"egg")
print(m.hexdigest())
#5a680543e062ec341ecf6b0047246a80
注意:文件体积越大,计算摘要的时间也越长。通常把大体积的文件,分成多块,再来计算摘要。
4 os模块
os模块是与操作系统交互的一个接口
os.walk(path) 以迭代器的形式返回当前目录下的子文件夹和子文件名
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.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所指向的文件或者目录的最后修改时间
os.path.getsize(path) 返回path的大小
5 sys模块
sys模块是python解释器的
sys.argv 命令行参数List,第一个元素[0]是程序本身路径
sys.exit(n) 退出程序,正常退出时exit(0)
sys.version 获取Python解释程序的版本信息
sys.maxint 最大的Int值
sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform 返回操作系统平台名称
sys.modules 返回当前加载的所有模块
6 序列化
http://www.cnblogs.com/yangzhenwei123/p/6802018.html
7 logging模块
import logging
logging.debug("debug message")
logging.info("info message")
logging.warning("warning message")
logging.error("error message")
logging.critical("critical message")
结果:
WARNING:root:warning message
ERROR:root:error message
CRITICAL:root:critical message
日志的等级(由低到高):NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL
在默认情况下,python中的logging模块是将日志打印到标准输出,且只显示大于等于WARNING级别的日志,默认的日志格式为日志级别:Logger名称:用户:输出消息。
1 配置日志级别,日志格式,输出位置
logging.basicConfig(level=logging.INFO, #调节日志打印等级
format="%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s",
datefmt="%a %d %b %Y %H:%M:%M", #调节上面%(asctime)s 显示的时间格式
filename="test.log", #把日志定向到文件名 ,config只能选择一种显示方式:屏幕或文件
# filemode="a", #文件的写模式 "w"和"a",默认追加写
)
logging.debug("debug message")
logging.info("info message")
logging.warning("waring message")
logging.error("error message")
logging.critical("critical message")
test.log文件的内容:
Mon 01 May 2017 17:17:17 logging_module.py [line:26] INFO info message
Mon 01 May 2017 17:17:17 logging_module.py [line:28] WARNING waring message
Mon 01 May 2017 17:17:17 logging_module.py [line:30] ERROR error message
Mon 01 May 2017 17:17:17 logging_module.py [line:32] CRITICAL critical message
在logging.basicConfig()函数中可通过具体参数来修改logging模块的默认设置:
filename:用来指定文件名创建FileHandler(后边会具体讲解handler的概念),将日志文件重定向到文件。默认是标准输出。
filemode:文件的打开模式,默认是“a”,还可以指定为“w”。
format:指定handler使用的日志显示格式。
datefmt:指定日期格式时间。
leverl:设置rootlogger(后边会讲解具体概念)的日志级别 。
stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件。
(f=open('test.log','w')),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
format参数中可用的格式化串:
%(name)s Logger的名字
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s用户输出的消息
2 logger对象
从上述我们可以了解了logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical()(分别用以记录不同级别的日志信息),logging.basicConfig()(用默认日志格式(Formatter)为日志系统建立一个默认的流处理器(StreamHandler),设置基础配置(如日志级别等)并加到root logger(根Logger)中)这几个logging模块级别的函数,另外还有一个模块级别的函数是logging.getLogger([name])(返回一个logger对象,如果没有指定名字将返回root logger)
logger=logging.getLogger() #产生一个logger对象
logger.setLevel(logging.INFO) #设置日志的等级
fh=logging.FileHandler("logger2.log") #产生一个要存储日志的文件的句柄
sh=logging.StreamHandler() #产生一个流(打印到屏幕)句柄
formatter=logging.Formatter("%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s")
fh.setFormatter(formatter)
sh.setFormatter(formatter)
logger.addHandler(fh) #给日志对象添加一个日志文件句柄,将日志输出定向到日志文件
logger.addHandler(sh) #给日志对象添加一个流句柄,将日志输出定向到屏幕文件
#不同于config只能定向到屏幕或者文件,logger对象能同时定向到这两个。所以推荐使用logger
logger.debug("debug message")
logger.info("info message")
logger.warning("waring message")
logger.error("error message")
logger.critical("critical message")
结果:
2017-05-01 18:00:56,892 logging_module.py [line:61] INFO info message
2017-05-01 18:00:56,892 logging_module.py [line:63] WARNING waring message
2017-05-01 18:00:56,892 logging_module.py [line:65] ERROR error message
2017-05-01 18:00:56,892 logging_module.py [line:67] CRITICAL critical message
logging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。
Logger是一个是一个树形层级结构,输出信息之前都要获得一个Logger(如果没有显示的获取则自动创建并使用root Logger,如第一个例子所示)。
logger=logging.getLogger()返回一个默认的Logger也即root Logger,并应用默认的日志级别、Handler和Formatter设置。
当然也可以通过Logger.setLevel(lel)指定最低的日志级别,可用的日志级别有logging.DEBUG、logging.INFO、logging.WARNING、logging.ERROR、logging.CRITICAL。
Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical()输出不同级别的日志,只有日志等级大于或等于设置的日志级别的日志才会被输出。
import logging
logger1=logging.getLogger("mylogger1")
logger1.setLevel(logging.DEBUG)
logger2=logging.getLogger("mylogger1")
logger2.setLevel(logging.INFO)
fh=logging.FileHandler("logger1.log")
sh=logging.StreamHandler()
formatter=logging.Formatter("%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s [%(name)s] %(message)s")
fh.setFormatter(formatter)
sh.setFormatter(formatter)
logger1.addHandler(fh)
logger1.addHandler(sh)
logger2.addHandler(fh)
logger2.addHandler(sh)
logger1.debug("debug message")
logger1.info("info message")
logger1.warning("waring message")
logger1.error("error message")
logger1.critical("critical message")
logger2.debug("debug message")
logger2.info("info message")
logger2.warning("waring message")
logger2.error("error message")
logger2.critical("critical message")
结果:
2017-05-01 21:05:43,001 logging_module.py [line:92] INFO [mylogger1] info message
2017-05-01 21:05:43,001 logging_module.py [line:93] WARNING [mylogger1] waring message
2017-05-01 21:05:43,001 logging_module.py [line:94] ERROR [mylogger1] error message
2017-05-01 21:05:43,001 logging_module.py [line:95] CRITICAL [mylogger1] critical message
2017-05-01 21:05:43,001 logging_module.py [line:98] INFO [mylogger1] info message
2017-05-01 21:05:43,001 logging_module.py [line:99] WARNING [mylogger1] waring message
2017-05-01 21:05:43,001 logging_module.py [line:100] ERROR [mylogger1] error message
2017-05-01 21:05:43,001 logging_module.py [line:101] CRITICAL [mylogger1] critical message
logger1和logger2对应同一个Logger实例。所以后一次的设置setLevel()会覆盖前一次设置的值。
import logging
logger1=logging.getLogger()
logger2=logging.getLogger("mylogger1")
fh=logging.FileHandler("logger1.log")
sh=logging.StreamHandler()
formatter=logging.Formatter("%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s [%(name)s] %(message)s")
fh.setFormatter(formatter)
sh.setFormatter(formatter)
logger1.addHandler(fh)
logger1.addHandler(sh)
logger2.addHandler(fh)
logger2.addHandler(sh)
logger1.debug("debug message")
logger1.info("info message")
logger1.warning("waring message")
logger1.error("error message")
logger1.critical("critical message")
logger2.debug("debug message")
logger2.info("info message")
logger2.warning("waring message")
logger2.error("error message")
logger2.critical("critical message")
结果:
2017-05-01 21:14:17,051 logging_module.py [line:93] WARNING [root] waring message
2017-05-01 21:14:17,051 logging_module.py [line:94] ERROR [root] error message
2017-05-01 21:14:17,051 logging_module.py [line:95] CRITICAL [root] critical message
2017-05-01 21:14:17,051 logging_module.py [line:99] WARNING [mylogger1] waring message
2017-05-01 21:14:17,051 logging_module.py [line:99] WARNING [mylogger1] waring message
2017-05-01 21:14:17,051 logging_module.py [line:100] ERROR [mylogger1] error message
2017-05-01 21:14:17,051 logging_module.py [line:100] ERROR [mylogger1] error message
2017-05-01 21:14:17,051 logging_module.py [line:101] CRITICAL [mylogger1] critical message
2017-05-01 21:14:17,051 logging_module.py [line:101] CRITICAL [mylogger1] critical message
通过logger1 = logging.getLogger()显示的创建了root Logger,而logger2 = logging.getLogger('mylogger1')创建了root Logger的孩子(root.)mylogger1。而孩子,孙子,重孙……既会将消息分发给他的handler进行处理也会传递给所有的祖先Logger处理。
孩子,孙子,重孙……可逐层继承来自祖先的日志级别、Handler、Filter设置,也可以通过Logger.setLevel(lel)、Logger.addHandler(hdlr)、Logger.removeHandler(hdlr)、Logger.addFilter(filt)、Logger.removeFilter(filt)。设置自己特别的日志级别、Handler、Filter。若不设置则使用继承来的值。
3 Filter
限制只有满足过滤规则的日志才会输出。
比如我们定义了filter = logging.Filter('a.b.c'),并将这个Filter添加到了一个Handler上,则使用该Handler的Logger中只有名字带 a.b.c前缀的Logger才能输出其日志。
filter = logging.Filter('mylogger')
logger.addFilter(filter)
这是只对logger这个对象进行筛选
如果想对所有的对象进行筛选,则:
filter = logging.Filter('mylogger')
fh.addFilter(filter)
ch.addFilter(filter)
这样,所有添加fh或者ch的logger对象都会进行筛选。
logging模块http://www.cnblogs.com/yuanchenqi/articles/5732581.html
8 re模块
我们以前对字符串的处理,如调用内置的字符串方法,这种叫完全匹配。
而正则表达式提供的是模糊匹配。
正则表达式是通过元字符来进行模糊匹配的。
1 常用的元字符: . * + ? {} [] \ () | ^ $
# . 匹配除\n换行以外的任何符号
# * 左边的一个符号 有0个或以上
# + 左边的一个符号 有1个或以上
# ? 左边的一个符号 有0个或1个
#{n} 左边的一个符号 有n个
#{n,} 左边的一个符号 有n个或以上
#{n,m} 左边的一个符号 有n到m个
# ^ 以什么开始
# $ 以什么结尾
# | 或者 a|b a或b
#[] 字符集 从字符集里取一个出来 或
#把大部分符号都变成普通符号,如* , +
#部分有特殊意义 - ^ \
# \ 转义符 可以把没有特殊意义的符号变成有特殊意义的符号,也可以把有特殊意义的符号变成没有特殊意义的符号。
2 或 |
| 会把规则表达式分成多个部分来匹配。通常与()配合使用
res=re.findall("www\.(?:oldboy)|(?:baidu)\.com","www.oldboy.com") #此时|把匹配规则分成前后两个部分
print(res) #['www.oldboy']
res=re.findall("www\.(?:oldboy|baidu)\.com","www.oldboy.com")
print(res) #['www.oldboy.com']
3 元字符之转义符\
反斜杠后边跟元字符去除特殊功能,比如\.
反斜杠后边跟普通字符实现特殊功能,比如\d
\d 匹配任何十进制数;它相当于类 [0-9]。
\D 匹配任何非数字字符;它相当于类 [^0-9]。
\s 匹配任何空白字符;它相当于类 [ \t\n\r\f\v]。
\S 匹配任何非空白字符;它相当于类 [^ \t\n\r\f\v]。
\w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
\W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]
\b 匹配一个特殊字符边界,比如空格 ,&,#等#### 元字符之转义符\
转义\时,需要注意:
#print(re.findall("c\l","abc\l")) #sre_constants.error: bad escape \l at position 1
#在python,\是有特殊意义的,要打"\",需要"\\",前面那个"\"把后面那个转义成普通符号
#print(re.findall(r"c\l","abc\l")) #sre_constants.error: bad escape \l at position 1
#此时仍然会报错,因为正则处理的时候,"\"也是转义符,需要用"\\",最后书写时则需要四个(3个也可以)
print(re.findall("c\\\\l","abc\l"))
#如果不用上述,也可以用r,原生字符串来处理
print(re.findall(r"c\\l","abc\l")) #['c\\l']
由此可见,解释器执行正则表达式时,会先把规则部分转义一次,再交由正则处理。所以如果需要转义,那么规则部分转义两次。字符串表达式(要处理的)部分转义一次,且字符串部分如果\与右边的字符(或字符串)在ascii表没有对应,那么此时""不发生转义,代表普通的"",如\l表示"\l"两个字符,此时转不转义左边的""都不会出错。但要注意是数字的情况,"\数字"通常都会发生转义,此时必须写双斜杠"\",如ord("\5") ,结果是5;ord("\127") ,结果是87。也可以注意pycharm中这些字符颜色的变化,就能避免这个问题。
4 分组()
- 未命名分组
注意:如果规则里面有多个未命名分组,这些分组会被封装在一个元组中。
print(re.findall("(ab)+def","abababdef")) #['ab']
print(re.findall("(\d)+def","123456def")) #['6']
print(re.findall("(?:ab)+def","abababdef")) #['abababdef']
分组()的优先级比其他的元字符的高,默认情况匹配成功,只返回分组内的值。在括号内添加“?:”,可以取消分组的优先级。
- 命名分组
res=re.search(r"(?P<author>yuanchenqi)/articles/(?P<id>\d+)",r"http://www.cnblogs.com/yuanchenqi/articles/5732581.html")
print(res) #如果能找到,就返回<_sre.SRE_Match object; span=(23, 50), match='yuanchenqi/articles/5732581'>
#不能找到就返回None
print(res.group("author")) #yuanchenqi
print(res.group("id")) #5732581
此时,相当于给分组添加了别名,可通过别名来提取分组内的匹配条件。
5 re模块提供的匹配的方法:
正则表达式的语法:re.func("regulation","string_expression")
# re.findall() 返回的是列表
s=re.findall("\d+","ad324ds434")
print(s) #['324', '434']
# re.finditer()
#将结果以迭代器返回
s=re.finditer("\d+","ad324ds434")
#print(s) <callable_iterator object at 0x000001FC5D932908>
print(next(s)) #<_sre.SRE_Match object; span=(2, 5), match='324'>
print(next(s).group()) #434
#re.search() 只获取匹配的第一个结果,以字符串形式返回
res=re.search("\d+","ad324ds434")
print(res.group()) #324
print(res.group()) #324
#re.match() 只在字符串开始的位置匹配,没有就报错
res=re.match("\d+","2323ad324ds434")
print(res.group()) #2323
#re.split() 以“规则”为分隔符,返回列表(类比字符串里的split())
s=re.split("\d+","fhd56fdfg787ttrtf7878grtr789",2)
print(s) #['fhd', 'fdfg', 'ttrtf7878grtr789']
s=re.split("l","hello world")
print(s) #['he', '', 'o wor', 'd']
#re.sub() 替换
res=re.sub("[a-z]","A","32dsfef4343fde434f445f3re",2)
print(res) #32AAfef4343fde434f445f3re
#re.subn() 替换,返回替换后的结果并且返回替换的次数,以元组方式返回
res=re.subn("[a-z]","A","32dsfef4343fde434f445f3re")
print(res) #('32AAAAA4343AAA434A445A3AA', 12)
#re.compile("规则") 并用返回的对象去调用上面的方法。
print(re.findall("\d+","dwe32343dwr434f545"))
res=re.compile("\d+")
ret=res.findall("fefer34343fe443fe433")
print(ret)
6 贪婪匹配和非贪婪匹配
- 贪婪匹配,即最大长度的匹配结果
贪婪匹配的量词,也叫匹配优先量词,如{m,n} 、 {m} 、 ? 、 * 、 +
print(re.findall("\d+","123456def243545dghh434")) #['123456', '243545', '434']
- 非贪婪匹配(懒惰模式)
匹配优先量词后加上“?”,即变成属于非贪婪模式的量词,也叫做忽略优先量词。有{m,n}?、{m,}? 、?? 、*? 和 +?。即在匹配优先量词后面添加?。
非贪婪模式,就是在整个表达式匹配成功的前提下,尽可能少的匹配,也就是所谓的“非贪婪”,通俗点讲,就是找到一个想要的捡起来就行了,至于还有没有没捡的就不管了。
# print(re.findall("\d+?","123456def243545dghh434"))
#['1', '2', '3', '4', '5', '6', '2', '4', '3', '5', '4', '5', '4', '3', '4']
贪婪匹配和非贪婪匹配 http://www.jb51.net/article/31491.htm
模块的相关链接:http://www.cnblogs.com/yuanchenqi/articles/5732581.html
http://www.cnblogs.com/yuanchenqi/articles/6766020.html