【问题标题】:datetime strptime - set format to ignore trailing part of stringdatetime strptime - 设置格式以忽略字符串的尾随部分
【发布时间】:2015-05-30 20:19:03
【问题描述】:

我有一个可变长度的字符串,我想为strptime 提供一个格式,以便忽略字符串的其余部分。让我举例说明。我有类似的东西

9/4/2013,00:00:00,7.8,7.4,9.53
10/4/2013,00:00:00,8.64,7.4,9.53

我想要一种格式,使命令strptime(line,format) 可以读取这些行。像format='%d/%m/%Y,%H:%M:%S*' 这样的东西,虽然我知道那行不通。我想我的问题有点类似于this one,但没有答案可以帮助我,而且我的问题更糟,因为我的字符串的全长可能会有所不同。我感觉dateutil 可以解决我的问题,但我找不到可以解决问题的方法。

我可能会做类似strptime(''.join(line.split(',')[:2]),format) 的事情,但我不想诉诸于与用户相关的问题。

【问题讨论】:

  • 这归结为对 strptime 的增强请求,以允许任意正则表达式,至少在字符串的尾部:format='%d/%m/%Y,%H:%M:%S.*'。这是一个常见的要求,非常值得考虑。事实上people have been asking for it for 13+ years.

标签: python string parsing datetime trailing


【解决方案1】:

也使用正则表达式,因为 python datetime 不允许忽略字符,此版本使用无捕获组(抱歉示例与您的问题无关):

import datetime, re

date_re = re.compile(r'([^.]+)(?:\.[0-9]+) (\+[0-9]+)')
date_str = "2018-09-06 04:15:18.334232115 +0000"

date_str = " ".join(date_re.search(date_str).groups())

date_obj = datetime.datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S %z")

像@marjin 建议的那样使用正则表达式要好得多,因此您的代码更易于理解且易于更新。

【讨论】:

    【解决方案2】:

    看看datetime-glob,这是我们开发的一个模块,用于从文件列表中解析日期/时间。您可以使用datetime_glob.PatternSegment 解析任意字符串:

    >>> import datetime_glob
    >>> patseg = datetime_glob.parse_pattern_segment('%-d/%-m/%Y,%H:%M:%S*')
    >>> match = datetime_glob.match_segment('9/4/2013,01:02:03,7.8,7.4,9.53',
                                            patseg)
    >>> match.as_datetime()
    datetime.datetime(2013, 4, 9, 1, 2, 3)
    

    【讨论】:

      【解决方案3】:

      要在不拆分时间字符串和丢弃额外文本的情况下构建格式字符串,只需将额外文本包含在格式字符串中即可。 t[t.index(',',t.index(',') + 1):] 是额外的文字。

      from datetime import datetime
      l = ['9/4/2013,00:00:00,7.8,7.4,9.53', '10/4/2013,00:00:00,8.64,7.4,9.53']
      for t in l:
          print datetime.strptime(t,'%d/%m/%Y,%H:%M:%S'+t[t.index(',',t.index(',')+1):])
      

      如果字符串中有'%'可以用空字符串代替。

      l = ['9/4/2013,00:00:00,7.8,7.4,9.53', '10/4/2013,00:00:00,8.64,7.4,9.53']
      for t in l:
          t = t.replace('%','')
          fmt = '%d/%m/%Y,%H:%M:%S' + t[t.index(',',t.index(',')+1):]
          print datetime.strptime(t, fmt)
      

      或者用字符串切片和静态格式字符串,

      for t in l:
              print datetime.strptime(t[:t.find(',',t.find(',')+1)],'%d/%m/%Y,%H:%M:%S')
      

      2013-04-09 00:00:00
      2013-04-10 00:00:00

      【讨论】:

      • 那么如果额外的字符串包含% 字符会发生什么?请注意,您实际上是在反向进行拆分;您正在拆分 remainder 并将其添加到格式字符串中。
      • 在日期和时间字段中出现 % 的机会是正确的。我回答了 OP。
      • 对,但我也是,但它没有你的“解决方案”所存在的问题。有时答案确实是你不能这样做,但这是你解决问题的方法
      • 什么问题? OP 需要一个格式字符串。他已经知道拆分原始字符串了。
      • 我已经发表了评论,不,否决票不需要需要评论。
      【解决方案4】:

      您不能让datetime.strptime() 忽略部分输入。您的 only 选项实际上是首先拆分额外的文本。

      所以是的,你必须拆分并重新加入你的字符串:

      format = '%d/%m/%Y,%H:%M:%S'
      datetime.strptime(','.join(line.split(',', 2)[:2]), format)
      

      或找到其他方法来提取信息。您可以使用正则表达式,例如:

      datetime_pattern = re.compile(r'(\d{1,2}/\d{1,2}/\d{4},\d{2}:\d{2}:\d{2})')
      format = '%d/%m/%Y,%H:%M:%S'
      datetime.strptime(datetime_pattern.search(line).group(), format)
      

      【讨论】:

      • OP 不想拆分多余的文本。他想要一个格式字符串来读取字符串。
      • @NizamMohamed:OP 要求一些不存在的东西。
      • 我已经给出了解决方案。
      • @NizamMohamed:不,实际上,你没有。您正在做完全相同的事情,但拆分了 other 部分。这比它解决的问题更多,因为现在您还必须担心转义元字符。
      • 是的,无论哪种方式,您都必须修改每个输入行,或者修改每个输入行的格式。太糟糕了。
      猜你喜欢
      • 1970-01-01
      • 2013-11-11
      • 1970-01-01
      • 2011-05-02
      • 1970-01-01
      • 2016-06-05
      • 1970-01-01
      • 2017-05-07
      • 2015-09-14
      相关资源
      最近更新 更多