我知道有很多问题可以从字符串中提取日期时间,例如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'
我可以搜索的任何线索或方向吗?
答案 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}}