项目:将带有美国风格日期的文件改名为欧洲风格日期
假定你的老板用电子邮件发给你上千个文件,文件名包含美国风格的日期(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 firectory
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)# 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

python实践项目(八)相关推荐

  1. python实践项目-shop

    python实践项目-shop 练习 文件打开/保存 cmd应用 prettytable 场景 使用CMD程序,实现商店管理 python3+pycharm 源码 getPicke.py 初始化PIC ...

  2. python实践项目(九)

    项目:将一个文件夹备份到一个 ZIP 文件 假定你正在做一个项目,它的文件保存在C:\AlsPythonBook 文件夹中.你担心工作会丢失, 所以希望为整个文件夹创建一个ZIP 文件, 作为&quo ...

  3. python实践项目(七)

    项目1:生成随机的测验试卷文件 假如你是一位地理老师,班上有35 名学生, 你希望进行美国各州首府的一个小测验.不妙的是,班里有几个坏蛋,你无法确信学生不会作弊.你希望随机调整问题的次序, 这样每份试 ...

  4. Python|实验项目八例

    实验一:编写一个Python程序,模拟一个自动柜员机(ATM)验证用户输入密码的操作.ATM提示用户输入密码,如果用户输入正确密码,ATM输出密码正确信息,然后终止程序. #exp1_1 def ma ...

  5. Python实践项目——LSB隐写术

    一.项目背景 1.隐写术 隐写术是一门关于信息隐藏的技巧与科学,所谓信息隐藏指的是不让除预期的接收者之外的任何人知晓信息的传递事件或者信息的内容. 2.LSB 隐写术 LSB 隐写术是一种图像隐写术技 ...

  6. python实践项目(五)

    参考书目:<Python编程快速上手-让繁琐工作自动化>,下载地址:我是下载链接,请点击 练习1:口令保管箱 你可能在许多不同网站上拥有账号,每个账号使用相同的口令是个坏习惯.如果这些网站 ...

  7. python实践项目(四)

    练习1:好玩游戏的物品清单 你在创建一个好玩的视频游戏.用于对玩家物品清单建模的数据结构是一个字典.其中键是字符串,描述清单中的物品,值是一个整型值,说明玩家有多少该物品.例如,字典值{'rope': ...

  8. python实践项目(一)

    Collatz 序列:        要求1:编写一个名为 collatz()的函数,它有一个名为 number 的参数.如果参数是偶数,那么 collatz()就打印出 number // 2, 并 ...

  9. python练习项目八——下载所有XKCD 漫画

    项目:下载所有XKCD 漫画 背景 博客和其他经常更新的网站通常有一个首页,其中有最新的帖子,以及一个"前一篇"按钮,将你带到以前的帖子.然后那个帖子也有一个"前一篇&q ...

最新文章

  1. 使用Oracle instantClient代替Oracle Client安装
  2. latex如何设置字体并加粗_如何设置微信昵称字体大小加粗变斜???
  3. 转:Community Clips 使用指南
  4. git bash here创建项目无法选择m_git 版本控制初学者指南
  5. java 获取service_Java service层获取HttpServletRequest工具类的方法
  6. KD_Tree 算法
  7. 基于多源数据画像的失败用例智能分析
  8. live555 windows下编译以及修订
  9. Golang实践录:使用gin框架实现转发功能:管理后端服务
  10. python能做什么-python都能干什么用
  11. java毕业设计外卖管理系统mybatis+源码+调试部署+系统+数据库+lw
  12. Cuba 设置debug模式
  13. photoshop中如何在6寸相纸上打印1寸照片12张3X4模式(手动拖动模式)
  14. Python札记 -- 切片赋值
  15. HTML+CSS实现网页分页页码
  16. 输出 2~n之间所有素数,并求和,n由键盘输入。素数是只能被1和自身整除的整数。要求编写函数判断自然数x是否为素数
  17. Docker 与虚拟机有何不同?
  18. 基于正点原子阿波罗 STM32F429 上手RT-Thread
  19. 北京理工大学重点用人单位推荐
  20. sakai2.8安装-总算装上了

热门文章

  1. 最近一段时间的流水帐。
  2. 2-6 刮刮乐和双色球
  3. STL源码剖析-map
  4. nginx热升级实现
  5. codova添加android慢_从 0 开始学 Linux 内核之 android 内核栈溢出 ROP 利用
  6. 【免费毕设】基于PHP实现的WEB图片共享系统(源代码+论文)
  7. 如何获取web视频数据流的传输?小姐姐的视频都被我爬下来了,这谁顶得住
  8. oracle 10g 扩表空间,Oracle 10g 表空间管理(一)
  9. docker的文件流处理_迁移到微服务与DevOps,微服务和Docker容器的全面实用指南
  10. mysql使用中文报错,hibernate mysql 插入中文错误