Переименование командного файла: нулевое время заполнения с помощью регулярного выражения - PullRequest
0 голосов
/ 05 ноября 2018

У меня есть целый набор файлов (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\1-11-2018 \2h0\3m', file)
    os.rename(file, newfile)

Но это все еще не работает полностью, как мне хотелось бы, так как это не изменило бы часов до 10. Что еще я мог попробовать?

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Для простоты я предлагаю перейти к более старому шаблону old_pattern, предполагая, что ваши имена файлов ведут себя неправильно только с цифрами:

Поскольку комбинации имен файлов, соответствующих однозначному полю, которое необходимо преобразовать в любой позиции, но которые являются двузначными в других полях, потребуют длинного регулярного выражения для более явного перечисления, я предлагаю этот гораздо более простой, чтобы сопоставлять файлы с переименованием, что делает предположение, что в каталоге есть только этот совпадающий тип файла, поскольку он открывает его более широко, чтобы было проще писать и читать с первого взгляда - найти любое однозначное поле в имени файла (одно или несколько из них) - то есть. не цифра, цифра, не цифра:

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», то для этого потребуется специальная обработка - это может быть отдельный случай, а также добавление пробела в набор шаблонов регулярных выражений re.sub (т. Е. [-hm ]).

0 голосов
/ 05 ноября 2018

Вы можете добавить числа в именах файлов с помощью .zfill(2), используя лямбда-выражение, переданное в качестве аргумента замены в метод re.sub.

Кроме того, исправьте шаблон регулярного выражения, чтобы разрешить 1 или 2 цифры: (3[01]|[12][0-9]|0?[1-9]) для даты, (2[0-3]|[10]?\d) для часа (24 часа) и ([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 .

Тогда используйте:

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 документы:

Если repl является функцией, она вызывается для каждого неперекрывающегося вхождения pattern . Функция принимает один аргумент объекта сопоставления и возвращает строку замены.

...