文本处理领域的两个主要的工具是目录导航和一种称为正则表达式的技术。
目录导航是一个不同的操作系统真正给简单的程序带来大量麻烦 领域,因为三个主要的操作系统都以不同 的方式组织它们的目录,他们使用不同的字符分隔子目录。python考虑到了这种问题,提供了一系列的跨平台工具来执行目录和路径操作,当一直使用这些工具时,就可以完全消除这个困难。
正则表达式是指定一个非常简单的文本解析器的方法,对任意多行文本进行处理时,这种文本解析器的开销很低。
搜索文件、日志剪辑、邮件筛选
1 使用os模块导航文件系统
os.getcwd() 返回当前目录。
os.listdir(directory)返回一个存储在指定的directory目录中的文件名和子目录列表。
os.stat(path)返回一个关于文件或目录的信息的数值元组
st_mode:文件的访问权限
st_ino:节点数unix
st_dev:设备号
st_nlink:链接号unix
st_uid:所有者的用户ID
st_gid:所有者的组ID
st_size:文件的大小
st_atime:最后访问时间
st_mtime:最后修改时间
st_ctime:创建时间
os.path.split(path) 将路径分割为符合当前操作系统的组成名称。返回一个元组
os.path.join(components)将名称连接成为一个符合当前操作系统的路径
os.path.normcase(path)规范化路径的大小写,在unix下没有影响,因为文件名是区分大小写的,但是在windows下,操作系统在比较文件名的时候是忽略大小写的,所以在比较一个路径和其他路径之前运行normcase,python采用与操作系统相同的方法进行比较。也就是说,如果两个路径的区别仅在于字母的大小写,那么它们是相同的。在windows下函数返回一个全小写的路径并转换所有 斜杠为反斜杠。在windows下变为小写。
os.walk(top,topdown=True,onerror=None,followlinks=False) 迭代目录树,对于每个目录它创建一个由dirpath/dirnames/filesnames组成的三元组。它内置于python 用C编写,运行快。
top 是要遍历的目录地址
dirpath:当前正在遍历的地址
dirnames:是一个list 文件夹中所有的目录的名字(不包括子目录)
filesnames:是一个list 文件夹中所有的文件(不包括子目录)
topdow:True 优先遍历top目录,否则优先遍历top的子目录。
onerror callable对象,异常时调用
followlinks True遍历目录下快捷方式实际所指的目录。
>>> os.getcwd()
'E:\pythonscript'
>>> os.path.split(os.getcwd())
('E:\', 'pythonscript')
>>> os.stat('.')
os.stat_result(st_mode=16895, st_ino=4222124650805149, st_dev=3263911355, st_nlink=1, st_uid=0, st_gid=0, st_size=4096, st_atime=1570688392, st_mtime=1570688392, st_ctime=1565164077)
>>> os.listdir('.')
['ch5.py', 'ch51.py', 'ch6.py', 'ch7.py', 'ch8.py', 'food.py', 'foods.py', 'kitchen', 'leaningpython', 'log', 'meal.py', 'script1.py', 'setup.py', '__pycache__']
>>>
>>> keyvaluelist=os.walk(r"E://pythonscript",topdown=True,onerror=None,followlinks=True)
>>> for root,dirs,files in keyvaluelist:
print(root)
for d in dirs:
print(os.path.join(root,d))
for f in files:
print(os.path.join(root,f))
import os,os.path
import re
def print_pdf(root,dires,files):
for file in files:
path=os.path.join(root,file)
path=os.path.normcase(path)
if re.search(r".*.pdf",path):
print(path)
>>> for root,dirs,files in os.walk('.'):
print_pdf(root,dirs,files)
>>> import os
>>> os.path.splitext(r"E:/pythonscript/ch5.py")
('E:/pythonscript/ch5', '.py')
形式r"string constant" 告诉python字符串常量应该禁止对反斜杠做出任何特殊处理。
“ "是一个单个字母长度的、相当于一个新行的字符串,而r" "是一个两个字母长度的字符串,表示一个反斜杠字符后面跟着一个字母"n"
>>> print(" ")
>>> print(r"
")
>>>
过滤掉空格记录:
import os,os.path
import re
def print_pdf(root,dires,files):
for file in files:
path=os.path.join(root,file)
path=os.path.normcase(path)
if not re.search(r".*.py",path):continue
if re.search(r" ",path):continue
print(path)
for root,dirs,files in os.walk('.'):
print_pdf(root,dirs,files)
2 使用正则表达式和re模块
通配符:. 句点匹配字符串中的任何一个字符,
如果要查询 .可以使用反斜杠转义特殊字符,或原生字符串 在字符串前面加入一个”r"
>>> import re
>>> s=('xxx','abcxxxabc','xyx','abc','x.x','axa','axxxxa','axxya')
>>> a=filter((lambda s:re.match(r"xxx",s)),s)
>>> print(*a)
xxx
re.match函数只从它的输入 开始搜索匹配。
re.search函数从输入的任何地方找到字符串
>>> b=filter((lambda s:re.search(r"xxx",s)),s)
>>> print(*b)
xxx abcxxxabc axxxxa
>>> c=filter((lambda s:re.search(r"x.x",s)),s)
>>> print(*c)
xxx abcxxxabc xyx x.x axxxxa
>>> c=filter((lambda s:re.search("x.x",s)),s)
>>> print(*c)
xxx abcxxxabc xyx x.x axxxxa
>>> c=filter((lambda s:re.search("x.x",s)),s) #通过转义特殊字符匹配句点
>>> print(*c)
x.x
>>> e=filter((lambda s:re.search(r"x.*x",s)),s)# 使用显号搜索任间数量的X,星号可以匹配它前面的一串任意字符 0个或更多的字符
>>> print(*e)
xxx abcxxxabc xyx x.x axxxxa axxya
>>> f=filter((lambda s:re.search(r"x.+x",s)),s) # +加号匹配1个或更多个字符
>>> print(*f)
xxx abcxxxabc xyx x.x axxxxa
>>> g=filter((lambda s:re.search(r"c+",s)),s)
>>> print(*g)
abcxxxabc abc
>>> g=filter((lambda s:re.search(r"c",s)),s)
>>> print(*g)
abcxxxabc abc
>>> g=filter((lambda s:re.search(r"c*",s)),s)
>>> print(*g)
xxx abcxxxabc xyx abc x.x axa axxxxa axxya
>>> ss=('c','cc','ccx','xxxc')
>>> h=filter(lambda x:re.search(r"[^c]*$",x),ss)
>>> print(*h)
c cc ccx xxxc
>>> h=filter(lambda x:re.search(r"[^c]",x),ss)
>>> print(*h)
ccx xxxc
>>> h=filter(lambda x:re.search(r"[^c$]",x),ss)
>>> print(*h)
ccx xxxc
>>> h=filter(lambda x:re.search(r"[^c]$",x),ss)
>>> print(*h)
ccx
>>> h=filter(lambda x:re.search(r"^[^c]$",x),ss) * 方括号表示要匹配的特殊字符集,开头^,意味着不出现在集合中的所有字符
>>> print(*h)
开始和结束:使用 ^ 和 $特殊字符 从头到尾不包含
小结
文本处理脚本一般是简短的、有用的、可重用的程序,它们或者为一次性和临时的应用编写,或者作为大型数据处理系统的组件使用。
使用os.walk函数遍历文件系统
在编写的函数中放入搜索标准并传递给os.walk函数
正则表达式能够在每个通过os.walk函数找到的文件上执行测试。
在python解释器中以交互方式试验正则表达式,以保证它们正确工作
import os,os.path
import re
def print_pdf(root,dires,files):
for file in files:
path=os.path.join(root,file)
path=os.path.normcase(path)
if not re.search(r".*.pdf",path):continue
if re.search(r".*python.+.pdf",path): #取文件名中包含python的pdf(r"python")
print(path)
for root,dirs,files in os.walk('/'):
print_pdf(root,dirs,files)
筛选不包含python的pdf文件
import os,os.path
import re
def print_no_pdf(root,dires,files):
for file in files:
path=os.path.join(root,file)
path=os.path.normcase(path)
if not re.search(r".*.pdf",path):continue
if re.search(r"python",path):continue
print(path)
for root,dirs,files in os.walk('/'):
print_no_pdf(root,dirs,files)