以不同格式的字符串返回特定值

时间:2019-07-01 03:02:38

标签: python python-3.x date

如何使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 :(得分:0)

相关但不同:Convert “unknown format” strings to datetime objects?

此问题有所不同,因为字符串不仅是日期,而且还嵌入在字符串中。我将此问题视为“如何在格式不一致的字符串中查找日期?”

我使用dateparser 0.7.1,可以找到文档here。因为字符串的格式是未知的并且可能与每个字符串不同,所以我计算了字符串中的所有字符ngram,然后将它们解析为日期。然后,将最常见的日期作为正确的输出返回。这是一种缓慢且效率低下的方法,但是对于这里的要求,这是我能提出的最好的方法:

  • 未知格式
  • 字符串不仅包含日期
  • 日期可以在字符串中的任意位置:

以下代码:

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_lengthmax_date_length之间的所有字符ngram,日期通常不能任意长或短于默认值5(尽管有可能,例如,如果日期格式为1/1,例如1月1日)
  • 使用dateparser.parse将ngram解析为日期,并忽略所有无法解析的
  • 过滤掉过去或将来年份过长的年份(这是已发布示例的问题,1632被认为是"Desktop/Application,1632,26/02"的年份)
  • 获取为字符ngram找到的最常见日期

此解决方案适用于问题中包含的三个示例。再次注意,这是一种非常低效的方法,可能无法在所有情况下都起作用(例如,对于字符串中的多个日期,它将中断)。

一种更有效的方法是使用正则表达式从每个字符串中仅提取日期字符串,然后使用datetime.strptime。参见strftime() and strptime() Behavior