批处理文件重命名:使用正则表达式的零填充时间?
Batch file rename: zero padding time with regex?
我有一整套文件 (10.000+),文件名中包含日期和时间。问题是日期和时间没有用零填充,导致排序出现问题。
文件名的格式为:output 5-11-2018 9h0m.xml
我想要的格式是:output 05-11-2018 09h00m.xml
我搜索过不同的解决方案,但大多数似乎都使用拆分字符串然后重新组合它们。这看起来很麻烦,因为在我的例子中,日、月、小时和分钟需要分开、填充然后重新组合。
我认为正则表达式可能会给我一些更好的解决方案,但我不太明白。
我根据 Wiktor Stribiżew 的建议编辑了我的原始代码,即您不能在替换中使用正则表达式,而是使用组:
import os
import glob
import re
old_format = 'output [1-9]-11-2018 [1-2]?[1-9]h[0-9]m.xml'
dir = r'D:\Gebruikers\<user>\Documents\datatest\'
old_pattern = re.compile(r'([1-9])-11-2018 ([1-2][1-9])h([0-9])m')
filelist = glob.glob(os.path.join(dir, old_format))
for file in filelist:
print file
newfile = re.sub(old_pattern, r'0-11-2018 h0m', file)
os.rename(file, newfile)
但这仍然不能完全按照我的意愿运行,因为它不会改变 10 点以下的小时数。我还能尝试什么?
您可以使用作为替换参数传递给 re.sub
方法的 lambda 表达式,用 .zfill(2)
填充文件名中的数字。
此外,修复正则表达式模式以允许 1 或 2 位数字:(3[01]|[12][0-9]|0?[1-9])
表示日期,(2[0-3]|[10]?\d)
表示一小时 (24h),([0-5]?[0-9])
表示分钟:
old_pattern = re.compile(r'\b(3[01]|[12][0-9]|0?[1-9])-11-2018 (2[0-3]|[10]?\d)h([0-5]?[0-9])m')
参见regex demo。
然后使用:
for file in filelist:
newfile = re.sub(old_pattern, lambda x: '{}-11-2018 {}h{}m'.format(x.group(1).zfill(2), x.group(2).zfill(2), x.group(3).zfill(2)), file)
os.rename(file, newfile)
参见 Python re.sub
文档:
If repl is a function, it is called for every non-overlapping occurrence of pattern. The function takes a single match object argument, and returns the replacement string.
为了简单起见,我建议使用 old_pattern 更通用,假设您的文件名只是与数字有关:
因为文件名组合匹配一个需要在任何位置转换但在其他字段中是双位数的文件名组合需要一个很长的正则表达式来更明确地列出,我建议使用这个更简单的方法来匹配文件重命名,它假设目录中只有这种匹配类型的文件,因为它会更广泛地打开它,以便更简单地编写和读取一目了然 - 找到文件名中的任何单个数字字段(一个或多个) - IE。非数字,数字,非数字:
old_format = r'output\.*\D\d\D.*\.xml'
固定 re.sub 语句可以是:
newfile = re.sub(r'\D(\d)[hm-]', lambda x: x.group()[0]+x.group()[1].zfill(2)+x.group()[2], file)
这也会捕获 unicode 非 ascii 数字,除非设置了适当的 re 模块标志。
如果年份(例如 2018 年)可能只给出“18”,那么它需要对此进行特殊处理 - 可能是单独的情况,并且还要在 [=27= 中添加 space ]正则表达式模式集(即[-hm ]
)。
我有一整套文件 (10.000+),文件名中包含日期和时间。问题是日期和时间没有用零填充,导致排序出现问题。
文件名的格式为:output 5-11-2018 9h0m.xml
我想要的格式是:output 05-11-2018 09h00m.xml
我搜索过不同的解决方案,但大多数似乎都使用拆分字符串然后重新组合它们。这看起来很麻烦,因为在我的例子中,日、月、小时和分钟需要分开、填充然后重新组合。
我认为正则表达式可能会给我一些更好的解决方案,但我不太明白。
我根据 Wiktor Stribiżew 的建议编辑了我的原始代码,即您不能在替换中使用正则表达式,而是使用组:
import os
import glob
import re
old_format = 'output [1-9]-11-2018 [1-2]?[1-9]h[0-9]m.xml'
dir = r'D:\Gebruikers\<user>\Documents\datatest\'
old_pattern = re.compile(r'([1-9])-11-2018 ([1-2][1-9])h([0-9])m')
filelist = glob.glob(os.path.join(dir, old_format))
for file in filelist:
print file
newfile = re.sub(old_pattern, r'0-11-2018 h0m', file)
os.rename(file, newfile)
但这仍然不能完全按照我的意愿运行,因为它不会改变 10 点以下的小时数。我还能尝试什么?
您可以使用作为替换参数传递给 re.sub
方法的 lambda 表达式,用 .zfill(2)
填充文件名中的数字。
此外,修复正则表达式模式以允许 1 或 2 位数字:(3[01]|[12][0-9]|0?[1-9])
表示日期,(2[0-3]|[10]?\d)
表示一小时 (24h),([0-5]?[0-9])
表示分钟:
old_pattern = re.compile(r'\b(3[01]|[12][0-9]|0?[1-9])-11-2018 (2[0-3]|[10]?\d)h([0-5]?[0-9])m')
参见regex demo。
然后使用:
for file in filelist:
newfile = re.sub(old_pattern, lambda x: '{}-11-2018 {}h{}m'.format(x.group(1).zfill(2), x.group(2).zfill(2), x.group(3).zfill(2)), file)
os.rename(file, newfile)
参见 Python re.sub
文档:
If repl is a function, it is called for every non-overlapping occurrence of pattern. The function takes a single match object argument, and returns the replacement string.
为了简单起见,我建议使用 old_pattern 更通用,假设您的文件名只是与数字有关:
因为文件名组合匹配一个需要在任何位置转换但在其他字段中是双位数的文件名组合需要一个很长的正则表达式来更明确地列出,我建议使用这个更简单的方法来匹配文件重命名,它假设目录中只有这种匹配类型的文件,因为它会更广泛地打开它,以便更简单地编写和读取一目了然 - 找到文件名中的任何单个数字字段(一个或多个) - IE。非数字,数字,非数字:
old_format = r'output\.*\D\d\D.*\.xml'
固定 re.sub 语句可以是:
newfile = re.sub(r'\D(\d)[hm-]', lambda x: x.group()[0]+x.group()[1].zfill(2)+x.group()[2], file)
这也会捕获 unicode 非 ascii 数字,除非设置了适当的 re 模块标志。
如果年份(例如 2018 年)可能只给出“18”,那么它需要对此进行特殊处理 - 可能是单独的情况,并且还要在 [=27= 中添加 space ]正则表达式模式集(即[-hm ]
)。