Возврат определенных значений в строке другого формата - PullRequest
0 голосов
/ 01 июля 2019

Как мне заставить python автоматически искать определенный тип данных (например, дату) в строке другого формата?

Пример ввода:

"-rwxr-xr-x 1 user usergrp 1632 Feb 26 11:03 Desktop/Application"
"Desktop/Application,1632,26/02"
"26/02/19 - Desktop/Application - 1632"

Выходные данные для этих примеров должны быть 26 Feb 19.

1 Ответ

0 голосов
/ 01 июля 2019

Связанные, но разные: Преобразовать строки «неизвестного формата» в объекты даты и времени?

Эта проблема другая, потому что строки - это не просто даты, а встроенные в строки. Я рассматриваю эту проблему как «Как найти даты в строках с несовместимыми форматами?»

Я использую 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 () Поведение .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...