Связанные, но разные: Преобразовать строки «неизвестного формата» в объекты даты и времени?
Эта проблема другая, потому что строки - это не просто даты, а встроенные в строки. Я рассматриваю эту проблему как «Как найти даты в строках с несовместимыми форматами?»
Я использую dateparser 0.7.1 , документацию можно найти здесь . Поскольку формат строк неизвестен и может отличаться от каждой строки, я вычисляю все символьные строки в строке и затем анализирую их как даты. Наиболее распространенная дата затем возвращается в качестве правильного вывода. Это медленный и неэффективный подход, но это лучшее, что я могу придумать для требований здесь:
- неизвестный формат
- строки содержат не только даты
- даты могут быть в произвольных позициях в строке:
Код ниже:
from collections import Counter
import dateparser
def extract_date(min_date_length=5, max_date_length=15, min_year_value=2000, max_year_value=2020):
val = "Feb 26 11:03 Desktop/Application"
val = "Desktop/Application,1632,26/02"
val = "26/02/19 - Desktop/Application - 1632"
grams = []
for n in range(min_date_length, max_date_length):
grams.extend(val[i:i + n] for i in range(len(val) - n + 1))
dates = []
for gram in grams:
out = dateparser.parse(gram)
if out and min_year_value <= out.year <= max_year_value:
dates.append(out)
date, _count = Counter(dates).most_common(1)[0]
print(date)
return date
if __name__ == "__main__":
extract_date()
Как это работает:
- вычисляет все символьные диаграммы в диапазоне (от
min_date_length
до max_date_length
) по соображениям эффективности, и даты обычно не могут быть произвольно длинными или намного короче, чем значение по умолчанию 5 (хотя это возможно, например, если формат даты 1/1
для 1 января, например)
- использует
dateparser.parse
для разбора ngram как даты и игнорирует все те, которые он не может разобрать
- отфильтровывают те, для которых год слишком далек в прошлом или слишком далек в будущем (это проблема с опубликованными примерами,
1632
считается годом для "Desktop/Application,1632,26/02"
)
- получить наиболее распространенную дату, найденную для символов ngrams
Это решение работает на трех примерах, которые были включены в вопрос. Обратите внимание, что это очень неэффективный подход, и он может работать не во всех ситуациях (например, для нескольких дат в строке он будет разбит).
Более эффективный подход - использовать регулярное выражение для извлечения только строк даты из каждой строки, а затем использовать datetime.strptime
. См. strftime () и strptime () Поведение .