如何从数组中的类似日期的字符串中删除不需要的字符?

时间:2016-10-19 23:18:11

标签: arrays ruby string date

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

[ "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替换不需要的空格,但它只删除了冒号。我怎么能删除它?

3 个答案:

答案 0 :(得分: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:无效日期

适当的时候。你应该尽可能地利用这样的核心功能。

答案 1 :(得分: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#strftime。日期格式字符串在strftime的文档中进行了解释。

假设

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 :(得分:0)

只需在:上拆分并弃掉其余部分:

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!