【问题标题】:How can I remove unwanted characters from date-like strings within an array?如何从数组中类似日期的字符串中删除不需要的字符?
【发布时间】:2017-03-01 18:44:00
【问题描述】:

我有一个包含多个日期和时间的数组:

[ "24/Oct/2014:13:43:15 -0600",
  "25/Oct/2014:14:47:25 -0600",
  "24/Oct/2014:13:46:15 -0600" ]

我一直在努力。

["24/Oct/2014", "25/Oct/2014", "24/Oct/2014"]

我尝试使用gsub 将不需要的内容替换为空格,但它只删除了冒号。我怎样才能删除它?

【问题讨论】:

    标签: arrays ruby string date


    【解决方案1】:
    arr = ["24/Oct/2014:13:43:15 -0600",
           "05/Oct/2014:14:47:25 -0600",
           "24/Oct/2014:13:46:15 -0600"]
    

    如果你确定日期字符串的格式是正确的,并且代表有效的日期,你可以简单地写

    arr.map { |s| s[0,11] }
      #=> ["24/Oct/2014", "05/Oct/2014", "24/Oct/2014"]
    

    另一方面,如果您希望检查日期字符串的有效性,您可能希望将每个日期字符串转换为日期对象,然后将该对象转换为所需的字符串格式。这样,如果日期字符串无效,则会引发异常。

    require 'date'
    
    arr.map { |s| DateTime.strptime(s, '%d/%b/%Y:%H:%M:%S %z').strftime('%d/%b/%Y') }
      #=> ["24/Oct/2014", "05/Oct/2014", "24/Oct/2014"] 
    

    这使用方法DateTime::strptimeDateTime#strftimestrftime 的文档中解释了日期格式字符串。

    假设

    arr = ["42/Oct/2014:13:43:15 -0600"]
    

    然后

    arr.map { |s| DateTime.strptime(s, '%d/%b/%Y:%H:%M:%S %z').strftime('%d/%b/%Y') }
      #=> ArgumentError: invalid date
    

    您可以改用DateTime::parse 而不是strptime 将日期字符串转换为Date 对象,但它在识别无效日期方面非常薄弱。例如:

    DateTime.parse "123456/01-02abc"
      #=> #<DateTime: 123456-01-02T00:00:00+00:00 ((46812439j,0s,0n),...
    DateTime.parse "-7/8"
      #=> #<DateTime: 2016-07-08T00:00:00+00:00 ((2457578j,0s,0n),...
    DateTime.parse "He demanded 1/2 of the pie"
      #=> #<DateTime: 2016-01-02T00:00:00+00:00 ((2457390j,0s,0n),...
    

    【讨论】:

      【解决方案2】:

      字符串的许多替代方案

      有很多方法可以将日期字符串作为 String 对象进行操作。在您的情况下,两个这样的选项包括String#partitionString#match。例如:

      dates = [
        "24/Oct/2014:13:43:15 -0600",
        "25/Oct/2014:14:47:25 -0600",
        "24/Oct/2014:13:46:15 -0600"
      ]
      
      dates.map { |date| date.match(/\A[^:]+/).to_s }
      dates.map { |date| date.partition(?:)[0] }
      

      这两种方法都将返回一个字符串数组,如下所示:

      #=> ["24/Oct/2014", "25/Oct/2014", "24/Oct/2014"]
      

      注意事项

      将此类日期作为 String 对象处理的主要问题是您假设字符串表示将始终相同。如果您知道自己的数据,那很好,但通常最好将日期 视为 日期。例如,您可以使用Date#parse,带或不带Date#strftime,自动处理常见的表示,如下所示:

      require 'date'
      
      # Remove #to_s if you want to return actual Date objects for
      # further processing, rather than an array of strings.
      dates.map { |date| Date.parse(date).to_s }
      #=> ["2016-10-24", "2016-10-25", "2016-10-24"]
      
      # This will only return strings, but that's what you originally
      # asked for.
      dates.map { |date| Date.parse(date).strftime '%d/%b/%Y' }
      #=> ["24/Oct/2016", "25/Oct/2016", "24/Oct/2016"]
      

      Date 和 DateTime 库也包含其他解析器。当然,如果您使用非标准输入格式,您可以将Date#strptime 与自定义模板一起使用。

      这里的重点是修改 String 对象是有效的,但通常最好将日期处理为 Date 或 DateTime 对象以避免边缘情况、验证输入并引发异常,例如:

      dates.map { |date| Date.rfc2822 date }
      

      ArgumentError: 无效日期

      在适当的时候。您绝对应该尽可能利用这样的核心功能。

      【讨论】:

        【解决方案3】:

        只需拆分 : 并丢弃其余部分:

        times = [ "24/Oct/2014:13:43:15 -0600", "25/Oct/2014:14:47:25 -0600", "24/Oct/2014:13:46:15 -0600" ]
        
        times.map do |time|
          time.split(':').first
        end
        
        # => ["24/Oct/2014", "25/Oct/2014", "24/Oct/2014"]
        

        如果您想就地执行此操作并修改您的数组,请使用map!

        【讨论】:

        • 调用 ruby​​ 数组 times 是个好主意吗?
        • 这是一个时间数组,但只要不与保留关键字冲突,您几乎可以随意调用它。 times 不是其中之一。
        猜你喜欢
        • 2011-12-24
        • 2016-02-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-15
        • 2011-08-13
        • 2016-06-29
        相关资源
        最近更新 更多