如何从长字符串中只获取日期字符串
how to get only date string from a long string
我知道有很多问答可以从字符串中提取日期时间,例如dateutil.parser,从字符串中提取日期时间
import dateutil.parser as dparser
dparser.parse('something sep 28 2017 something',fuzzy=True).date()
output: datetime.date(2017, 9, 28)
但我的问题是如何知道字符串的哪一部分导致了这次提取,例如我想要一个也 returns 我 'sep 28 2017'
的功能
datetime, datetime_str = get_date_str('something sep 28 2017 something')
outputs: datetime.date(2017, 9, 28), 'sep 28 2017'
有什么线索或方向可以搜索吗?
有趣的问题!没有直接的方法可以使用 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()
解决问题)。
扩展到与@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 步:删除标记并忽略 space 元素
for i in excl_str:
if i != ' ':
ostr = ostr.replace(i,'')
return ostr
给出最终输出
ostr: 'sep 28 2017 '
注意:步骤 2 是必需的,因为如果任何较短的标记是较长标记的子集,则会导致问题。例如,在这种情况下,如果删除遵循 ('something ', ' ', 'something abcd')
的顺序,替换过程将从 something abcd
中删除 something
,并且 abcd
永远不会被删除,以 'sep 28 2017 abcd'
我知道有很多问答可以从字符串中提取日期时间,例如dateutil.parser,从字符串中提取日期时间
import dateutil.parser as dparser
dparser.parse('something sep 28 2017 something',fuzzy=True).date()
output: datetime.date(2017, 9, 28)
但我的问题是如何知道字符串的哪一部分导致了这次提取,例如我想要一个也 returns 我 'sep 28 2017'
的功能datetime, datetime_str = get_date_str('something sep 28 2017 something')
outputs: datetime.date(2017, 9, 28), 'sep 28 2017'
有什么线索或方向可以搜索吗?
有趣的问题!没有直接的方法可以使用 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()
解决问题)。
扩展到与@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 步:删除标记并忽略 space 元素
for i in excl_str:
if i != ' ':
ostr = ostr.replace(i,'')
return ostr
给出最终输出
ostr: 'sep 28 2017 '
注意:步骤 2 是必需的,因为如果任何较短的标记是较长标记的子集,则会导致问题。例如,在这种情况下,如果删除遵循 ('something ', ' ', 'something abcd')
的顺序,替换过程将从 something abcd
中删除 something
,并且 abcd
永远不会被删除,以 'sep 28 2017 abcd'