Извлечение даты из имени файла с помощью импорта re в python

#python #regex

#python #регулярное выражение

Вопрос:

Мое имя файла выглядит следующим образом:

 show_data_paris_12112019.xlsx
  

Я хочу извлечь только дату, и я попробовал этот скрипт:

 date = os.path.basename(xls)
pattern = r'(?<=_)_*(?=.xlsx)'

re.search(pattern, date).group(0)
event_date = re.search(pattern, date).group(0)
event_date_obj = datetime.strptime (event_date, '%Y%m%d')
  

но это дает мне ошибки. Как я могу это исправить?

Спасибо.

Комментарии:

1. Объект ‘NoneType’ не имеет атрибута ‘group’, подобного этому

2. Таким образом, поиск завершается неудачей, и он возвращается None .

3. Отличный инструмент для тестирования / разработки регулярных выражений: regex101.com/r/MgBArI/1 Я добавил (фиксированную версию) вашего регулярного выражения и тестовую строку. Не стесняйтесь поиграть с ним и посмотреть, что соответствует результату. Очень полезный инструмент.

4. в таких случаях, когда шаблон не является сложным, следует ли просто использовать обычные строковые методы вместо re ? например, то же самое может быть достигнуто с помощью xls.split("_")[-1].split(".")[0]

Ответ №1:

Мне кажется, что используемое вами регулярное выражение также является ошибкой, и поэтому оно терпит неудачу при попытке group(0) получить пустое значение return.

Предполагая, что все ваши даты хранятся в виде цифр, следующее регулярное выражение, которое я сделал, похоже, работает довольно хорошо.

 (?!. _)d (?=.xlsx)
  

Следующая проблема заключается в том, что при форматировании даты возникает проблема с тем, как вы форматируете дату, для меня это выглядит так, что 12112019 будет 12/11/2019, очевидно, это также может быть 11/12/2019, но суть в том, что мы меняем способ форматирования даты strftime.

Итак, для формата даты / месяца / года мы бы использовали

 # %d%m%Y
event_date_obj = datetime.strptime(event_date, '%d%m%Y')
  

И мы бы просто поменяли местами %d и %m для формата месяц / дата / год. Итак, ваш полный код будет выглядеть примерно так:

 date = os.path.basename(xls)
pattern = "(?!. _)d (?=.xlsx)"
event_date = re.search(pattern, date).group(0)
event_date_obj = datetime.strptime (event_date, '%d%m%Y')
  

Для получения дополнительной информации о том, как использовать strftime, см. https://strftime.org /.

Ответ №2:

_* соответствует последовательности из нуля или более символов подчеркивания.

(?<=_) означает, что ему должен предшествовать символ подчеркивания.

(?=.xlsx) означает, что за ним должно следовать .xlsx .

Так что это будет соответствовать ___ in foo____.xlsx . Но оно не соответствует вашему имени файла, потому что данные находятся между подчеркиванием и .xlsx .

Вы должны соответствовать d , а не _* между lookbehind и lookahead.

 pattern = r'(?<=_)d (?=.xlsx)'
  

И если данные всегда состоят из 8 цифр, используйте d{8} , чтобы быть более конкретным.