[关闭]
@zhangyu756897669 2017-09-17T15:28:09.000000Z 字数 2972 阅读 569

项目:将具有美式日期的文件重命名为欧式日期

python官方文档


假如你的老板在名字中给你发送数以千计的美式日期文件(MM-DD-YYYY),并将它们重命名为欧式日期(DD-MM-YYYY)。这个无聊的任务可能需要一整天的时间来完成!我们来写一个程序来代替。

程序的功能如下:

这意味着代码将需要执行以下操作:

对于该项目,打开一个新的文件编辑器窗口,并将您的代码保存为renameDates.py。

步骤1:为美式日期创建正则表达式

该程序的第一部分将需要导入必要的模块并创建一个可以识别MM-DD-YYYY日期的正则表达式。。将它们作为TODO键入,可以方便地使用IDLE的CTRL-F查找功能进行查找。使您的代码如下所示:

  1. import shutil, os, re
  2. datePattern = re.compile(r"""^(.*?) # 所有文字之前的日期
  3. ((0|1)?\d)- # 一或两位月份数字
  4. ((0|1|2|3)?\d)- # 一或两位天数数字
  5. ((19|20)\d\d) #一年的四位数字
  6. (.*?)$ # 所有文字后的日期
  7. """, re.VERBOSE)
  8. #循环工作目录中的文件。
  9. # 跳过没有日期的文件。
  10. #获取文件名的不同部分。
  11. # 形成欧式文件名。
  12. # 获取完整的绝对文件路径。
  13. #重命名文件。

从本章你可以知道shutil.move()函数可以用来重命名文件:它的参数是要重命名的文件的名称和新的文件名。由于此函数存在于shutil模块中,因此必须导入该模块

但在重命名文件之前,您需要确定要重命名的文件。具有日期的文件名,如垃圾邮件4-4-1984.txt和01-03-2014eggs.zip应该被重命名,而没有日期的文件名如littlebrother.epub可以忽略。

您可以使用正则表达式来识别此模式。在顶部导入re模块后,调用re.compile()来创建一个Regex对象.第二个参数re.VERBOSE允许正则表达式字符串中的空格和注释使其更易于阅读。

正则表达式字符串以^(。*?)开头,以匹配可能在日期之前的文件名开头的任何文本。 ((0 | 1)?\ d)组匹配月份。第一个数字可以是0或1,所以正则表达式十二月份为12,二月为02。这个数字也是可选的,所以月份可能是4月4日或4日。当天的组是((0 | 1 | 2 | 3)?\ d)并遵循类似的逻辑; 3,03和31都是天数的有效号码。 (是的,这个正则表达式会接受一些无效的日期,如4-31-2014,2-29-2013和0-15-2014。日期有很多棘手的特殊情况,很容易错过,但为了简单起见,该程序中的正则表达式工作得很好。)

1885年是有效的一年,您可以在二十或二十一世纪寻找多年。这将使您的程序不会意外地匹配非日期文件名与日期格式,如10-10-1000.txt。

(。*?)$部分正则表达式将匹配日期之后的任何文本。

步骤2:从文件名中识别日期部分

接下来,程序将必须循环从os.listdir()返回的文件名字符串列表,并将它们与正则表达式匹配。应该跳过任何没有日期的文件。对于具有日期的文件名,匹配的文本将存储在几个变量中。使用以下代码填写程序中的前三个TO步骤:

  1. for amerFilename in os.listdir('.'):
  2. mo = datePattern.search(amerFilename)
  3. # Skip files without a date.
  4. if mo == None: #❶
  5. continue #❷
  6. # ❸ Get the different parts of the filename.
  7. beforePart = mo.group(1)
  8. monthPart = mo.group(2)
  9. dayPart = mo.group(4)
  10. yearPart = mo.group(6)
  11. afterPart = mo.group(8)

如果从search()方法返回的Match对象为None❶,则amerFilename中的文件名与正则表达式不匹配。 continue语句❷将跳过循环的其余部分,并转到下一个文件名。

否则,正则表达式组中匹配的各种字符串存储在名为beforePart,monthPart,dayPart,yearPart和afterPart❸的变量中。这些变量中的字符串将用于在下一步中形成欧式文件名。

为了保持组号的正确性,请尝试从头开始读取正则表达式,并在每次遇到开头圆括号时计数。不用考虑代码,只需写一个正则表达式的大纲。这可以帮助您可视化组。例如:

  1. datePattern = re.compile(r"""^(1) # all text before the date
  2. (2 (3) )- # one or two digits for the month
  3. (4 (5) )- # one or two digits for the day
  4. (6 (7) ) # four digits for the year
  5. (8)$ # all text after the date
  6. """, re.VERBOSE)

这里,数字1到8表示您编写的正则表达式中的组。使用正则表达式的轮廓,只需括号和组号,可以让您更清楚地了解正则表达式,然后再继续执行程序的其余部分。

步骤3:形成新文件名并重命名文件

作为最后一步,将上一步中创建的变量中的字符串与欧式日期连接:日期在月之前。在您的程序中填写三个剩余的TODO,代码如下:

  1. #形成欧式文件名。
  2. euroFilename = beforePart + dayPart + '-' + monthPart + '-' + yearPart + afterPart #❶
  3. #获取完整的绝对文件路径。
  4. absWorkingDir = os.path.abspath('.')
  5. amerFilename = os.path.join(absWorkingDir, amerFilename)
  6. euroFilename = os.path.join(absWorkingDir, euroFilename)
  7. # 重命名文件。
  8. print('Renaming "%s" to "%s"...' % (amerFilename, euroFilename)) # ❷
  9. #shutil.move(amerFilename, euroFilename) # 测试后取消注释 #❸

将连接的字符串存储在名为euroFilename❶的变量中。然后,将原始文件名以amerFilename和新的euroFilename变量传递给shutil.move()函数,以重命名文件❸。

该程序已将shutil.move()调用注释掉,而是打印将重命名为❷的文件名。首先运行这样的程序可以让您仔细检查文件是否正确重命名。然后,您可以取消注释shutil.move()调用并再次运行该程序以实际重命名文件。

类似程序的想法

还有很多其他原因可能需要重命名大量的文件。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注