描述:假设有这样一个任务,你需要将文件名中含有美国风格日期(MM-DD-YYYY)的部分更换为欧洲风格日期(DD-MM-YYYY),并且需要你处理的文件多达上千个
分析:检查当前工作目录的所有文件名,寻找美国风格的日期。如果找到,将改文件改名,交换月份和日期的位置,使之成为欧洲风格
程序需要做以下事情
1)创建一个正则表达式,可以识别美国风格日期的文本模式
2)调用 os.listdir() 找出工作目录中的所有文件
3)循环遍历每个文件名,利用该正则表达式检查他是否包含日期
4)如果它包含日期,用 shutil.move() 对该文件改名
完整代码如下
#! python3# renameDates.py - 将带有美国风格日期的文件更名为欧洲风格日期import os,re#为美国风格日期(MM-DD-YYYY)创建一个正则表达式def USADateSearch(flodername): USADateRegex=re.compile(r''' ^(.*?) #匹配文件名的全部 ((0|1)?\d) #匹配月份并分组 [-.] #分隔符为.或- ([0-3]?[0-9]) #匹配日期并分组 [-.] ((19|20)\d\d) (.*?)$ ''',re.VERBOSE) return USADateRegex.search(flodername)#在文件夹中创建文件#filename-包含多个文件名的列表#path-保存文件的路径def creatfile(filename,path): for filename in filename: fileAbsPath=os.path.join(path,filename) fileObj=open(fileAbsPath,'w') fileObj.close() path=r'C:\\Users\\Administrator.SC-s\\AppData\\Local\\Programs\\Python\\Python37\\forTest'foldername=['img-11.08.1995.txt','img-2333434.txt','img-21.05.1995.txt', 'img-12.08-1994.jpg','img-12.8.1994.gif','img-01.31.2030.txt', 'img-1.31.2030.jpg','img-05.05.1995.jpg','img-2-2-2011.txt']#设置当前工作目录(要用绝对路径的话就不用设置了)os.chdir(path)#先创建文件,只运行一次,先不要删除#creatfile(foldername,path)#定义一个主函数吧def main(): for filename in os.listdir(path): mo=USADateSearch(filename) if mo==None: print('-'*20) continue #这里必须把所有的值给取过来,不能只要月和日 #获得年月日各部分 beforePart=mo.group(1) monthPart=mo.group(2) dayPart=mo.group(4) yearPart=mo.group(5) afterPart=mo.group(7) #连接字符串 euroFilename=beforePart+dayPart+'-'+monthPart+'-'+yearPart+afterPart #获取绝对路径 amerFilename=os.path.join(path,filename) euroFilename=os.path.join(path,euroFilename) #重命名文件 print('Renaming "%s" to "%s"...' %(amerFilename,euroFilename)) os.rename(amerFilename,euroFilename)main()
step1:为美国风格日期(MM-DD-YYYY)创建一个正则表达式
可以根据每个数段的范围来拼写正则表达式,但又出现了一个问题,假如MM和DD的日期相同时可能会匹配到到错的,你不能确定他是欧洲风格还是美国风格,但是仔细思考过后,我只是把它们翻转过来,即是匹配到的是不准确的,但是因为他们相同,翻转后也是相同的
USADateRegex=re.compile(r'''( ^(.*?) #匹配文件名的全部 ((0|1)?\d) #匹配月份并分组 [-.] #分隔符为.或- ([0-3]?[0-9]) #匹配日期并分组 [-.] (19|20)\d\d (.*?)$ )''',re.VERBOSE)
step2:识别文件名中日期部分
for filename in os.listdir('.'): mo=USADateSearch(filename) if mo==None: print('-'*20) continue #这里必须把所有的值给取过来,不能只要月和日 #获得年月日各部分 beforePart=mo.group(1) monthPart=mo.group(2) dayPart=mo.group(4) yearPart=mo.group(5) afterPart=mo.group(7)
step3:构成新文件名,并对文件改名
#连接字符串 euroFilename=beforePart+dayPart+'-'+monthPart+'-'+yearPart+afterPart #获取绝对路径 amerFilename=os.path.join(path,filename) euroFilename=os.path.join(path,euroFilename) #重命名文件 print('Renaming "%s" to "%s"...' %(amerFilename,euroFilename)) #这里面之所以把占位符用双引号括起来,是因为用单引号需要转义,太麻烦 os.rename(amerFilename,euroFilename) #第一次运行时通常需要将这行注释,用然后检查上一行打印的信息,确认重命名争取了后再运行
遇到的问题:
管道匹配时句法
可能会存在的缺陷:
匹配日期的正则表达式有漏洞:如会匹配XXX31.08.1995 未纠正
调用 shutil.move() 来改名,会不会太浪费了,会造成无用的操作,毕竟我们只需要改变文件名(已解决)