常用模块(time、random、hashlib 、os、sys、logging、json、pickle、re )

一 time模块

时间表示形式

在Python中,通常有这三种方式来表示时间:时间戳(timestamp)、格式化时间字符串(Format String)、结构化时间字符串(struct time):
(1)时间戳(timestamp) :通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“time.time()”,返回的是float类型。

(2)格式化时间字符串(Format String):time.strftime("%Y-%m-%d %X")   Y:年 m:月 d:日  X:时分秒

(3)结构化时间字符串(struct time) :struct time元组共有9个元素共九个元素:(年tm_year,月tm_mon,日tm_mon,时tm_hour,分tm_min,秒tm_sec,这周的第几天 tm_wday,一年中第几天tm_yday等),time.localtime() 

小结:时间戳是计算机能够识别的时间;时间字符串是人能够看懂的时间;元组则是用来操作时间的

# <1> 时间戳

>>> import time
>>> time.time()      #--------------返回当前时间的时间戳

1493136727.099066

# <2> 格式化时间字符串
>>> time.strftime("%Y-%m-%d %X")
'2017-04-26 00:32:18'

# <3> 结构化时间字符串
>>> time.localtime()
time.struct_time(tm_year=2017, tm_mon=4, tm_mday=26,
                 tm_hour=0, tm_min=32, tm_sec=42, tm_wday=2,
                 tm_yday=116, tm_isdst=0)

几种时间形式的转换

(1)

 

#一 时间戳<---->结构化时间字符串:  localtime/gmtime   mktime

>>> 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)
>>> time.gmtime(3600*24)
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=2, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=2, tm_isdst=0)
>>> time.mktime(time.localtime()) 1513694512.0 #结构化时间字符串<---->格式化时间字符串: strftime/strptime >>> time.strftime("%Y-%m-%d %X", time.localtime()) 2017-12-19 22:43:32
>>> 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)

(2)

 

>>> time.asctime(time.localtime(312343423))  #结构化时间字符串转化为格式化时间字符串
'Sun Nov 25 10:03:43 1979'
>>> time.ctime(312343423)  #时间戳转化为格式化时间字符串
'Sun Nov 25 10:03:43 1979'

%a %b %d %H:%M:%S %Y   星期 月 日 时:分:秒 年

1 #--------------------------其他方法
2 # sleep(secs)
3 # 线程推迟指定的时间运行,单位为秒。

 二 random模块

>>> import random
>>> random.random()      # 大于0且小于1之间的小数
0.7664338663654585

>>> random.randint(1,5)  # 大于等于1且小于等于5之间的整数
2

>>> random.randrange(1,3) # 大于等于1且小于3之间的整数
1

>>> random.choice([1,'23',[4,5]])  # #1或者23或者[4,5]
1

>>> random.sample([1,'23',[4,5]],2) # #列表元素任意2个组合
[[4, 5], '23']

>>> random.uniform(1,3) #大于1小于3的小数
1.6270147180533838

>>> item=[1,3,5,7,9]
>>> random.shuffle(item) # 打乱次序
>>> item
[5, 1, 3, 7, 9]
>>> random.shuffle(item)
>>> item
[5, 9, 7, 1, 3]

练习:生成验证码

#以字母和数字,生成五个随机数验证码
import
random def v_code(): code = '' for i in range(5): num=random.randint(0,9) alf1=chr(random.randint(65,90)) alf2 = chr(random.randint(97,122)) add=random.choice([num,alf1,alf2]) code="".join([code,str(add)]) return code print(v_code())

三 hashlib 

Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等。

摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。

摘要算法就是通过摘要函数f()对任意长度的数据data计算出固定长度的摘要digest,目的是为了发现原始数据是否被人篡改过。

摘要算法之所以能指出数据是否被篡改过,就是因为摘要函数是一个单向函数,计算f(data)很容易,但通过digest反推data却非常困难。而且,对原始数据做一个bit的修改,都会导致计算出的摘要完全不同。

我们以常见的摘要算法MD5为例,计算出一个字符串的MD5值:

import hashlib
 
md5 = hashlib.md5()
md5.update('how to use md5 in python hashlib?'.encode("utf-8"))
print md5.hexdigest()

计算结果如下:
d26a53750bc40b38b65a520292f69306

如果数据量很大,可以分块多次调用update(),最后计算的结果是一样的:

md5 = hashlib.md5()
md5.update('how to use md5 in '.encode("utf-8"))
md5.update('python hashlib?'.encode("utf-8"))
print md5.hexdigest()

MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。另一种常见的摘要算法是SHA1,调用SHA1和调用MD5完全类似:

import hashlib
 
sha1 = hashlib.sha1()
sha1.update('how to use sha1 in '.encode("utf-8"))
sha1.update('python hashlib?'.encode("utf-8"))
print sha1.hexdigest()

SHA1的结果是160 bit字节,通常用一个40位的16进制字符串表示。比SHA1更安全的算法是SHA256和SHA512,不过越安全的算法越慢,而且摘要长度更长。

摘要算法应用

数据库密码加密:“加盐”

hashlib.md5("salt".encode("utf8"))

 

四 os模块

os模块是与操作系统交互的一个接口

'''
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir(r"文件路径")  改变当前脚本工作目录;相当于shell下cd
os.curdir  返回当前目录: ('.')
os.pardir  获取当前目录的父目录字符串名:('..')
os.makedirs('dirname1/dirname2')    可生成多层递归目录
os.mknod("textname") 创建空文件
os.removedirs('文件路径') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 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')#获取文件/目录信息 结果为一个列表st_atime:最后存储时间 st_mtime 修改时间 st_ctime 创建时间
            #网站浏览,缓存后再次访问,判断创建时间和有修改时间是否相同,如果不同,则需要到原网站去下载
                               os.path.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.realpath(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[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
            #路径拼接print(s1+os.sep+s2) ret =os.path.jion(s1,s2)#推荐

os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
os.path.getsize(path) 返回path的大小
'''
 

  os.path.normcase 规范化路径

在Linux和Mac平台上,该函数会原样返回path,在windows平台上会将路径中所有字符转换为小写,并将所有斜杠转换为饭斜杠。
>>> os.path.normcase('c:/windows\\system32\\')   
'c:\\windows\\system32\\'   
   

规范化路径,如..和/
>>> os.path.normpath('c://windows\\System32\\../Temp/')   
'c:\\windows\\Temp'   

 os.popen(), os.system()区别

os.system的结果只是命令执行结果的返回值,执行成功为0:

>>> a=os.system('ls')
Applications             Movies                   python-oldboy
Applications (Parallels) Music                    python3.sublime-build
Desktop                  Pictures                 rpro.log
Documents                Public                   test.py
Downloads                PycharmProjects          test.pyc
GitHub_source            Python_Assignment
Library                  oradiag_shane
>>> a
0

用os.popen就可以读出执行的内容,popen返回的是file read的对象,对其进行读取使用read(),就可看到执行的输出:

>>> b=os.popen('ls')
>>> b.read()
'Applications\nApplications (Parallels)\nDesktop\nDocuments\nDownloads\nGitHub_source\nLibrary\nMovies\nMusic\nPictures\nPublic\nPycharmProjects\nPython_Assignment\noradiag_shane\npython-oldboy\npython3.sublime-build\nrpro.log\ntest.py\ntest.pyc\n'
>>> type(b)
<class 'os._wrap_close'>
>>> 

可以看出,输出的结果比较特殊,带换行符\n

 

五 sys模块 

sys.argv           命令行参数List,第一个元素是程序本身路径
sys.platform       返回操作系统平台名称
sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值。
sys.path.insert(0,'module path’)、
sys.path.append(“module path”)

sys.exit(n) 退出正在运行的程序,正常退出时exit(0) sys.version 获取Python解释程序的版本信息 sys.maxint 最大的Int值 #python3不可用
sys.getsizeof(data)  得到数据大小

 

sys.argv           命令行参数List,第一个元素是程序本身路径

# encoding: utf-8
# filename: argv_test.py
import sys

# 获取脚本名字
print 'The name of this program is: %s' %(sys.argv[0])
# 获取参数列表
print 'The command line arguments are:'
for i in sys.argv:
    print i
# 统计参数个数
print 'There are %s arguments.'%(len(sys.argv)-1)

结果:

E:\p>python argv_test.py arg1 arg2 arg3
The name of this program is: argv_test.py
The command line arguments are:
argv_test.py
arg1
arg2
arg3
There are 3 arguments.

 

 六 logging模块

6.1 函数式简单配置(不能同时向屏幕和文件输出日志信息

import logging  
logging.debug('debug message')  
logging.info('info message')  
logging.warning('warning message')  
logging.error('error message')  
logging.critical('critical message') 

默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于warning级别的日志,这说明默认的日志级别设置为warning(日志级别等级critical > error > warning > info > debug),默认的日志格式为  日志级别:Logger名称:用户输出消息

灵活配置日志级别,日志格式,输出位置:

import logging  
logging.basicConfig(level=logging.DEBUG, #配置日志级别 
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', #配置日志格式 
                    datefmt='%Y-%m-%d %H:%M:%S', #时间输出格式
                    filename='/tmp/test.log', #日志信息向文件输出,不在屏幕输出 
                    filemode='w')  #打开文件的模式
  
logging.debug('debug message')  
logging.info('info message')  
logging.warning('warning message')  
logging.error('error message')  
logging.critical('critical message')

配置参数:

logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:

filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
format:指定handler使用的日志显示格式。
datefmt:指定日期时间格式。
level:设置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用户输出的消息
View Code

6.2 logger对象配置

import logging

logger = logging.getLogger()
# 创建一个handler,用于写入日志文件,指定写入的文件
fh = logging.FileHandler('test.log')

# 再创建一个handler,用于输出到控制台
ch = logging.StreamHandler()

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

fh.setFormatter(formatter)  #指定向日志文件输出的内容
ch.setFormatter(formatter) #指定向控制台输出的内容
logger.setLevel(logging.DEBUG) #指定输出的日志级别(文件和控制台)
logger.handlers.clear()# 清除控制句柄
logger.addHandler(fh) #logger对象可以添加多个fh和ch对象
logger.addHandler(ch) #logger对象可以添加多个fh和ch对象
logger.debug('logger debug message')
logger.info('logger info message')
logger.warning('logger warning message')
logger.error('logger error message')
logger.critical('logger critical message')

 logging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。另外,可以通过:logger.setLevel(logging.Debug)设置级别。

七 序列化模块

之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了,所以eval的重点还是通常用来执行一个字符串表达式,并返回表达式的值。

什么是序列化?

我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

json (只能序列化特定类型的数据,如果在文件自己写入json格式的数据,也能反序列化)

如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。

JSON表示的对象就是标准的JavaScript语言的对象一个子集,JSON和Python内置的数据类型对应如下:

dumps是将dict转化成str格式,loads是将str转化成dict格式。

dump和load也是类似的功能,只是与文件操作结合起来了。

json.dump(dict,f)

data=json.dumps(dict)

f.write(data)

data=json.load(f)

data=json.loads(f.read())

import json
i=10
s='hello'
t=(1,4,6)
l=[3,5,7]
d={'name':"yuan"}

json_str1=json.dumps(i)
json_str2=json.dumps(s)
json_str3=json.dumps(t)
json_str4=json.dumps(l)
json_str5=json.dumps(d)

print(json_str1)   #'10'
print(json_str2)   #'"hello"'
print(json_str3)   #'[1, 4, 6]' #元组对应的格式变化了,是json数据类型了
print(json_str4)   #'[3, 5, 7]' 
print(json_str5)   #'{"name": "yuan"}'  #键为“”引起来

 

 python在文本中的使用:

#----------------------------序列化
import json

dic={'name':'alvin','age':23,'sex':'male'}
print(type(dic))#<class 'dict'>

data=json.dumps(dic)
print("type",type(data))#<class 'str'>
print("data",data)


f=open('序列化对象','w')
f.write(data)  #-------------------等价于json.dump(dic,f),相当于进行了两步操作,一、转换成json字符串,将json字符串写入文件
f.close()


#-----------------------------反序列化<br>
import json
f=open('序列化对象')
new_data=json.loads(f.read())#  等价于data=json.load(f)

print(type(new_data))

 

 pickle(能处理任何数据类型,只有python解释器解读,处理成字节,文件不可读)

##----------------------------序列化
import pickle
 
dic={'name':'alvin','age':23,'sex':'male'}
 
print(type(dic))#<class 'dict'>
 
j=pickle.dumps(dic)
print(type(j))#<class 'bytes'>
 
 
f=open('序列化对象_pickle','wb')#注意是w是写入str,wb是写入bytes,j是'bytes'
f.write(j)  #-------------------等价于pickle.dump(dic,f)
 
f.close()
#-------------------------反序列化
import pickle
f=open('序列化对象_pickle','rb')
 
data=pickle.loads(f.read())#  等价于data=pickle.load(f)
 
print(data['age']) 

 re模块(正则,对字符串的模糊匹配)

就其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

import re

#1 re.findall
re.findall('a','alvin yuan')    #返回所有满足匹配条件的结果,放在列表里
#2 re.search re.search('a','alvin yuan').group()
# 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以 # 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,re.search()没有匹配,则返回None。 #3 re,match  re.match('a','abc').group() #同search,不过在字符串开始处进行匹配 #4 re.split ret=re.split('[ab]','abcd') #先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割 print(ret)#['', '', 'cd'] #5  re.sub su.subn ret=re.sub('\d','abc','alvin5yuan6',1) #(规则,替换内容,字符串,要替换的次数) print(ret)#alvinabcyuan6 ret=re.subn('\d','abc','alvin5yuan6')   #替换所有符合规则的字符串,以元组的形式返回替换结果合替换次数 print(ret)#('alvinabcyuanabc', 2)  #6  re.compile 编译规则,存起来随时调用 obj=re.compile('\d{3}') ret=obj.search('abc123eeee') print(ret.group())#123

 

字符匹配(普通字符,元字符):

1 普通字符:大多数字符和字母都会和自身匹配

2 元字符:. ^ $ * + ? { } [ ] | ( ) \

元字符之.* + ? { } ^ $ 

.通配符(除了\n换行符)

* [0,+00] 零到无穷多次

+ [1,+00] 一到无穷多次

? [0,1] 零到一次

{} {n,} n到无穷次

^:从字符串开始位置匹配
$:从字符串结尾匹配

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')
print(ret)#['4', '5', 'd', 'h', '3'] 

ret=re.findall('[\d]','45bdha3')
print(ret)#['4', '5', '3']

元字符之分组()  优先显示分组的内容

去掉组的优先级

print(re.findall("(ad)+","addd"))   #['ad']
print(re.findall("(ad)+yuan","adddyuangfsdui"))  #[]

print(re.findall("(?:ad)+yuan","adadyuangfsdui"))  #['adadyuan']    去掉组的优先级
print(re.findall("(?:\d)+yuan","adad678423yuang4234fsdui"))  #['678423yuan']

命名分组

r表示原生字符,也就是说不转义字符不需要再次被转义

比如你要表示‘\n’,可以这样:r'\n' 但是如果你不用原生字符 而是用字符串你得这样:‘\\n’

ret8=re.search(r"(?P<A>\w+)\\aticles\\(?P<id>\d{4})",r"yuan\aticles\1234")   #给组命名print(ret8.group("id"))  #调取组的内容
print(ret8.group("A"))

 

元字符之|

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']

 

元字符之转义符\

反斜杠后边跟元字符去除特殊功能,比如\.
反斜杠后边跟普通字符实现特殊功能,比如\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 匹配一个特殊字符边界,比如空格 ,&,#等

ret=re.findall('I\b','I am LIST')
print(ret)#[]

ret=re.findall(r'I\b','I am LIST')  #r将'I\b'转为原生字符串,\b匹配一个特殊边界
print(ret)#['I']

现在我们聊一聊\,先看下面两个匹配:

#-----------------------------eg1:
import re
ret=re.findall('c\l','abc\le')
print(ret)#[]

ret=re.findall('c\\l','abc\le')
print(ret)#[]

ret=re.findall('c\\\\l','abc\le')
print(ret)#['c\\l']    #显示的是两个\\,其实是一个\

ret=re.findall(r'c\\l','abc\le')
print(ret)#['c\\l']
 
#-----------------------------eg2:
#之所以选择\b是因为\b在ASCII表中是有意义的,\b在ASCII中退格的意思,拿给正则表达式就不能识别了

m = re.findall('\bblow', 'blow')
print(m)  #[]

m = re.findall(r'\bblow', 'blow')   #r先将\b不要转义,当成原生字符串拿给正则表达式
print(m)  #['blow'] 

 

posted @ 2017-04-26 17:34  shy车队破风手  阅读(452)  评论(0)    收藏  举报