python实践项目(八)
来源:互联网 发布:香港mac pro价格 编辑:程序博客网 时间:2024/05/29 14:19
项目:将带有美国风格日期的文件改名为欧洲风格日期
假定你的老板用电子邮件发给你上千个文件,文件名包含美国风格的日期(MM-DD-YYYY),需要将它们改名为欧洲风格的日期(DD-MM-YYYY)。手工 完成这个无聊的任务可能需要几天时间!让我们写一个程序来完成它。
下面是程序要做的事:
• 检查当前工作目录的所有文件名,寻找美国风格的日期。
• 如果找到,将该文件改名,交换月份和日期的位置,使之成为欧洲风格。
这意味着代码需要做下面的事情:
• 创建一个正则表达式,可以识别美国风格日期的文本模式。
• 调用 os.listdir(),找出工作目录中的所有文件。
• 循环遍历每个文件名,利用该正则表达式检查它是否包含日期。
• 如果它包含日期,用 shutil.move()对该文件改名。
将连接的字符串保存在名为 euroFilename的变量中。然后将 amerFilename中原来的文件名和新euroFilename变量传递给 shutil.move()函数, 将该文件改名。这个程序将shutil.move()调用注释掉,代之以打印出将被改名的文件名。先像这样运行程序,你可以确认文件改名是正确的。然后取消shutil.move()调用的注释, 再次运行该程序,确实将这些文件改名。
第 4 步:类似程序的想法
有很多其他的理由,导致你需要对大量的文件改名。
• 为文件名添加前缀,诸如添加spam_,将 eggs.txt改名为 spam_eggs.txt。
• 将欧洲风格日期的文件改名为美国风格日期。
• 删除文件名中的0,诸如 spam0042.txt。
假定你的老板用电子邮件发给你上千个文件,文件名包含美国风格的日期(MM-DD-YYYY),需要将它们改名为欧洲风格的日期(DD-MM-YYYY)。手工 完成这个无聊的任务可能需要几天时间!让我们写一个程序来完成它。
下面是程序要做的事:
• 检查当前工作目录的所有文件名,寻找美国风格的日期。
• 如果找到,将该文件改名,交换月份和日期的位置,使之成为欧洲风格。
这意味着代码需要做下面的事情:
• 创建一个正则表达式,可以识别美国风格日期的文本模式。
• 调用 os.listdir(),找出工作目录中的所有文件。
• 循环遍历每个文件名,利用该正则表达式检查它是否包含日期。
• 如果它包含日期,用 shutil.move()对该文件改名。
对于这个项目, 打开一个新的文件编辑器窗口, 将代码保存为 renameDates.py。
第 1 步:为美国风格的日期创建一个正则表达式
程序的第一部分需要导入必要的模块, 并创建一个正则表达式,它能识别MM-DD-YYYY格式的日期。 TODO 注释将提醒你,这个程序还要写什么。 将它们作为 TODO, 就很容易利用IDLE 的 Ctrl-F查找功能找到它们。让你的代码看起来像这样:
#! python3# renameDates.py - Renames filenames with American MM-DD-YYYY date format# to European DD-MM-YYYY. import shutil, os, re# Create a regex that matches files with the American date format. datePattern = re.compile(r"""^(.*?) # all text before the date((0|1)?\d)- # one or two digits for the month((0|1|2|3)?\d)- # one or two digits for the day((19|20)\d\d) # four digits for the year(.*?)$ # all text after the date """, re.VERBOSE)# TODO: Loop over the files in the working directory.# TODO: Skip files without a date.# TODO: Get the different parts of the filename.# TODO: Form the European-style filename.# TODO: Get the full, absolute file paths.# TODO: Rename the files.通过本章,你知道 shutil.move()函数可以用于文件改名: 它的参数是要改名的文件名,以及新的文件名。因为这个函数存在于shutil 模块中,所以你必须导入该模块。在为这些文件改名之前,需要确定哪些文件要改名。文件名如果包含spam4-4-1984.txt和 01-03-2014eggs.zip这样的日期,就应该改名,而文件名不包含日期的应该忽略,诸如 littlebrother.epub。可以用正则表达式来识别该模式。在开始导入re 模块后, 调用 re.compile()创建一个 Regex 对象。传入re.VERBOSE 作为第二参数, 这将在正则表达式字符串中允许空白字符和注释,让它更可读。正则表达式字符串以^(.*?)开始,匹配文件名开始处、日期出现之前的任何文本。((0|1)?\d)分组匹配月份。第一个数字可以是0 或 1, 所以正则表达式匹配12,作为十二月份, 也会匹配 02, 作为二月份。这个数字也是可选的, 所以四月份可以是04或 4。日期的分组是((0|1|2|3)?\d),它遵循类似的逻辑。3、 03和 31 是有效的日期数字(是的,这个正则表达式会接受一些无效的日期,诸如4-31-2014、 2-29-2013和 0-15-2014。日期有许多特例,很容易被遗漏。为了简单,这个程序中的正则表达式已经足够好了)。虽然1885 是一个有效的年份, 但你可能只在寻找20 世纪和 21世纪的年份。这防止了程序不小心匹配非日期的文件名,它们和日期格式类似, 诸如10-10-1000.txt。正则表达式的(.*?)$部分,将匹配日期之后的任何文本。
第 2 步:识别文件名中的日期部分
接下来, 程序将循环遍历os.listdir()返回的文件名字符串列表, 用这个正则表达式匹配它们。文件名不包含日期的文件将被忽略。如果文件名包含日期,匹配的文本将保存在几个变量中。用下面的代码代替程序中前3 个 TODO:
#! python3# renameDates.py - Renames filenames with American MM-DD-YYYY date format# to European DD-MM-YYYY.--snip--# Loop over the files in the working directory.for amerFilename in os.listdir('.'):mo = datePattern.search(amerFilename)# Skip files without a date. if mo == None: continue # Get the different parts of the filename. beforePart = mo.group(1) monthPart = mo.group(2) dayPart = mo.group(4) yearPart = mo.group(6) afterPart = mo.group(8)--snip--如果 search()方法返回的 Match 对象是 None, 那么amerFilename 中的文件名不匹配该正则表达式continue语句。将跳过循环剩下的部分, 转向下一个文件名。否则, 该正则表达式分组匹配的不同字符串, 将保存在名为beforePart、monthPart、dayPart、 yearPart和 afterPar 的变量中。这些变量中的字符串将在下一步中使用,用于构成欧洲风格的文件名。为了让分组编号直观, 请尝试从头阅读该正则表达式, 每遇到一个左括号就计数加一。不要考虑代码, 只是写下该正则表达式的框架。 这有助于使分组变得直观, 例如:
datePattern = re.compile(r"""^(1) # all text before the date(2 (3) )- # one or two digits for the month(4 (5) )- # one or two digits for the day(6 (7) ) # four digits for the year(8)$ # all text after the date""", re.VERBOSE)这里,编号 1 至8 代表了该正则表达式中的分组。写出该正则表达式的框架,其中只包含括号和分组编号。这让你更清楚地理解所写的正则表达式, 然后再转向程序中剩下的部分。
第 3 步:构成新文件名,并对文件改名
作为最后一步, 连接前一步生成的变量中的字符串,得到欧洲风格的日期:日期在月份之前。用下面的代码代替程序中最后3 个 TODO:
#! python3# renameDates.py - Renames filenames with American MM-DD-YYYY date format# to European DD-MM-YYYY.--snip--# Form the European-style filename. euroFilename = beforePart + dayPart + '-' + monthPart + '-' + yearPart +afterPart# Get the full, absolute file paths.absWorkingDir = os.path.abspath('.')amerFilename = os.path.join(absWorkingDir, amerFilename)euroFilename = os.path.join(absWorkingDir, euroFilename)# Rename the files. print('Renaming "%s" to "%s"...' % (amerFilename, euroFilename)) #shutil.move(amerFilename, euroFilename) # uncomment after testing
将连接的字符串保存在名为 euroFilename的变量中。然后将 amerFilename中原来的文件名和新euroFilename变量传递给 shutil.move()函数, 将该文件改名。这个程序将shutil.move()调用注释掉,代之以打印出将被改名的文件名。先像这样运行程序,你可以确认文件改名是正确的。然后取消shutil.move()调用的注释, 再次运行该程序,确实将这些文件改名。
第 4 步:类似程序的想法
有很多其他的理由,导致你需要对大量的文件改名。
• 为文件名添加前缀,诸如添加spam_,将 eggs.txt改名为 spam_eggs.txt。
• 将欧洲风格日期的文件改名为美国风格日期。
• 删除文件名中的0,诸如 spam0042.txt。
完整程序:
#-*-coding:utf-8-*-#! python3# renameDates.py - Renames filenames with American MM-DD-YYYY date format# to European DD-MM-YYYY.import shutil,os,re# create a regex that matches files with the American date format.datePattern = re.compile(r"""^(.*?) # all text before the date ((0|1)?\d)- # one or two digits for the month,begin with 0 or 1(optional) ((0|1|2|3)?\d)- # one or two digits for the day,begin with 0,1,2,3(optional) ((19|20)\d\d) # four digits for the year (.*?)$ # all text after the date """,re.VERBOSE) # 忽略正则表达式字符串中的空白符和注释# 分组表达式中分组编号每遇到一个左括号计数就加一# datePatter = re.compile(r"""^(1))# (2(3))-# (4(5))-# (6(7))# (8)$# """,re.VERBOSE)# Loop over the files in the working firectoryfor amerFilename in os.listdir('.'): mo = datePattern.search(amerFilename) # Skip files without a date. if mo == None: continue # Get the different parts of the filename. beforePart = mo.group(1) monthPart = mo.group(2) dayPart = mo.group(4) yearPart = mo.group(6) afterPart = mo.group(8) # From the European-style filename. euroFilename = beforePart + dayPart + '-' + monthPart + '-' + yearPart + afterPart # Get the full,absolute file paths. absWorkingDir = os.path.abspath('.') amerFilename = os.path.join(absWorkingDir,amerFilename) euroFilename = os.path.join(absWorkingDir,euroFilename) # Rename the files. print('Renaming "%s" to "%s"...'%(amerFilename,euroFilename)) #shutil.move(amerFilename,euroFilename) # uncomment after testing
阅读全文
1 0
- python实践项目(八)
- python实践项目(三)
- python实践项目(四)
- python实践项目(五)
- python实践项目(六)
- python实践项目(七)
- python实践项目(九)
- Python爬虫实践(八):正则表达式re模块(2)
- (八)驱动实践
- python实践项目(一)
- python实践项目(二)
- python计算机视觉项目实践
- python 文件读写项目实践
- 缺少python实践项目怎么办
- 实践项目八:优雅的实时火车票查看器(命令行版)
- 机器学习算法与Python实践之(八)朴素贝叶斯
- 项目开发(八)
- ios项目(八)
- String类型的时间转换成datetime类型,并实现减法
- navicat远程连接linux服务器的mysql
- React版本 AES 加密解密解析
- dubbo 简单使用
- java web 网上购书系统
- python实践项目(八)
- this关键字的应用
- 什么是java序列化,如何实现java序列化?或者请解释Serializable接口的作用
- 简单递归实现矩阵相乘
- (hadoop运维 一)cloudera-scm-agent dead
- 结构伪类选择器
- 使用360加固app,打多渠道包
- android 布局文件常见错误
- SSH2框架整合小案例