解析日期和时间

时间:2016-03-16 06:37:15

标签: python regex

我试图将month/year/day T hour:minute之类的字符串标记为['month', '/', 'year', '/', 'day', ' T ', 'hour', ':', 'minute'],但我正在尝试的正则表达式没有运气。任何人都可以对此有所了解,让我知道错误是什么?

>>> _tokenize_regex = 'year|month|day|hour|minute|second|.+'
>>> re.findall(_tokenize_regex, 'month/year/day T hour:minute')
['month', '/year/day T hour:minute']

最后一个选项.+找到了第二个findall - 结果项,但我认为这些选项已经过排名,因此.+只有在其他选项没有的情况下才会匹配。

更多例子:

'month.year somestring' -> ['month', '.', 'year', ' somestring']
'year-month-day hour:minute.second' -> ['year', '-', 'month', '-', 'day', ' ', 'hour', ':', 'minute', '.', 'second']

4 个答案:

答案 0 :(得分:2)

如何使用\w+匹配单词,[^\w\s]+匹配非单词,非空格字符?

>>> re.findall(r'\w+|[^\w\s]+', 'month/year/day T hour:minute')
['month', '/', 'year', '/', 'day', 'T', 'hour', ':', 'minute']

/不匹配yearmonth,... second,但匹配..+匹配字符串的结尾。

<强>更新

使用带有捕获组的re.split替代方法来保留separtors:

list(filter(None,
    re.split(r'(month|year|day|hour|minute|second|[^\w\s]+)', text)
))

〔实施例:

>>> import re 
>>> def tokenize(text):
...     tokens = re.split(r'(month|year|day|hour|minute|second|[^\w\s]+)', text)
...     return list(filter(None, tokens))
... 
>>> tokenize('month/year/day T hour:minute') 
['month', '/', 'year', '/', 'day', ' T ', 'hour', ':', 'minute']
>>> tokenize('month.year somestring') 
['month', '.', 'year', ' somestring']
>>> tokenize('year-month-day hour:minute.second') 
['year', '-', 'month', '-', 'day', ' ', 'hour', ':', 'minute', '.', 'second']

更新2

<{> re.findallnegative look-ahead assertion

re.findall(
    r'[^\w\s]+|\s+(?!(?:month|year|day|hour|minute|second))\w*\s*|\s+|\w+',
    text
)

答案 1 :(得分:2)

正则表达式中的问题是.+。特别是,在month匹配后,剩余的字符串将与year|month|day|hour|minute|second|.+匹配。与剩余字符串匹配的唯一表达式是.+。但由于这是贪婪的,它与字符串的其余部分相匹配。

根据我认为您尝试做的事情,您应该将.换成[/ T:]

此外,如果您实际上尝试匹配时间戳字符串,则应考虑使用strptime

答案 2 :(得分:1)

在python中使用凌乱的正则表达式并不是最好的一行。您可以尝试按步骤

执行此操作
>>> s = 'month/year/day T hour:minute'
>>> date,t,time = s.partition(' T ')
>>> month, year, day = date.split('/')
>>> hours, minutes = time.split(':')
>>> month, year, day, hours, minutes
('month', 'year', 'day', 'hour', 'minute')

为了与预期输出保持一致,您可以定义分隔符,并在分区和分割函数中使用这些分隔符而不是字符串。

dateSeparator = '/'
timeSeparator = ':'
tSeperator = ' T '

对于下一个查看代码的人来说,变量名比列表索引和自我记录更好。您可以随时自己创建列表。

答案 3 :(得分:0)

如果您正在使用真实日期,您可能需要检查它是否是真实日期或仅仅是数字组合。我建议使用特殊的datetime模块,它可以解析日期并检查它们。像这样:

    >>> import datetime
    >>> s='16/2016/03 T 23:52'
    >>> d = datetime.datetime.strptime(s, '%d/%Y/%m T %H:%M')
    >>> type(d)
    <class 'datetime.datetime'>
    >>> print(d)
    2016-03-16 23:52:00

这里有一个特殊的日期时间对象,对于日期操作非常舒适。更多信息和示例如下:https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior