如何从长字符串中仅获取日期字符串

时间:2018-12-04 02:58:42

标签: python-3.x datetime parsing python-dateutil

我知道有很多问题可以从字符串中提取日期时间,例如dateutil.parser,从字符串中提取日期时间

import dateutil.parser as dparser
dparser.parse('something sep 28 2017 something',fuzzy=True).date()

output: datetime.date(2017, 9, 28)

但是我的问题是如何知道字符串的哪一部分会导致提取,例如我想要一个也返回我“ 2017年9月28日”的函数

datetime, datetime_str = get_date_str('something sep 28 2017 something')
outputs: datetime.date(2017, 9, 28), 'sep 28 2017'

我可以搜索的任何线索或方向吗?

2 个答案:

答案 0 :(得分:1)

有趣的问题!没有直接的方法可以使用dateutil从较大的字符串中取出解析出的日期字符串。问题在于dateutil解析器甚至没有将此字符串用作中间结果,因为它确实动态地构建了将来的datetime对象的一部分,并且是逐个字符(source)地构建的。

尽管如此,它还会收集一个跳过的令牌列表,这可能是您最好的选择。按照此列表的顺序,您可以遍历令牌并替换首次出现的令牌:

from dateutil import parser


s = 'something sep 28 2017 something'
parsed_datetime, tokens = parser.parse(s, fuzzy_with_tokens=True)

for token in tokens:
    s = s.replace(token.lstrip(), "", 1)

print(s)  # prints "sep 28 2017"

尽管我不确定100%是否在所有可能的情况下都行得通,特别是在使用不同的空白字符时(请注意我必须如何解决.lstrip()的问题)。

答案 1 :(得分:1)

除了与@Paul讨论并遵循@alecxe的解决方案外,我还提出了以下解决方案,该解决方案适用于许多测试案例,使问题变得有些挑战:

步骤1:获取排除的令牌

import dateutil.parser as dparser

ostr = 'something sep 28 2017 something abcd'
_, excl_str = dparser.parse(ostr,fuzzy_with_tokens=True)

提供以下输出:

excl_str:     ('something ', ' ', 'something abcd')

第2步:按长度对令牌进行排名

excl_str = list(excl_str)
excl_str.sort(reverse=True,key = len)

给出排序的令牌列表:

excl_str:   ['something abcd', 'something ', ' ']

第3步:删除令牌并忽略空格元素

for i in excl_str:
    if i != ' ':
        ostr = ostr.replace(i,'') 
return ostr

给出最终输出

ostr:    'sep 28 2017 '

注意: :步骤2是必需的,因为如果任何较短的令牌是较长令牌的子集,它将引起问题。例如,在这种情况下,如果删除遵循('something ', ' ', 'something abcd')的顺序,则替换过程将从something中删除something abcd,并且abcd将永远不会被删除,最终以{ {1}}