我有一个看起来像这样的数组
[
"---n",
":date: 2018-07-31n :estimated_hours: 4.0n :remaining_hours: 4.0n ",
":date: 2018-08-01n :estimated_hours: 4.0n :remaining_hours: 4.0n ",
":date: 2018-08-22n :estimated_hours: 4.0n :remaining_hours: 0.0n "
]
我想选择键":date"
的所有值。我读到我可以使用Enumerable#select
,但我不知道该怎么做。谁能帮忙?
arr = ["---n",
":date: 2018-07-31n :estimated_hours: 4.0n :remaining_hours: 4.0n ",
":date: 2018-08-01n :estimated_hours: 4.0n :remaining_hours: 4.0n ",
":date: 2018-08-22n :estimated_hours: 4.0n :remaining_hours: 0.0n "]
arr.join.scan(/:date: (d{4}-d{2}-d{2})/).flatten
#=> ["2018-07-31", "2018-08-01", "2018-08-22"]
或
arr.join.scan(/(?<=:date: )d{4}-d{2}-d{2}/).flatten
#=> ["2018-07-31", "2018-08-01", "2018-08-22"]
(?<=:date: )
是一个积极的回头人,
或
arr.join.gsub(/(?<=:date: )d{4}-d{2}-d{2}/).to_a
#=> ["2018-07-31", "2018-08-01", "2018-08-22"]
最后一个选项看起来有点奇怪,因为我仅使用gsub
来创建一个生成与正则表达式匹配的枚举器。这是当 String#gsub 只有一个参数而没有块时的结果。在这种情况下,名称"gsub"
具有误导性,因为没有用其他字符串替换字符串。想想这种形式的方法被称为match_all
。我发现这种形式的gsub
有很多用途。
可以将String#[]
与正则表达式参数和正面回望一起使用:
input.flat_map { |e| e[/(?<=:date:s).*/] }.compact
#⇒ ["2018-07-31", "2018-08-01", "2018-08-22"]
由于这看起来很像YAML
(尽管它需要一点消毒(,我会选择:
a = [
"---n",
":date: 2018-07-31n :estimated_hours: 4.0n :remaining_hours: 4.0n ",
":date: 2018-08-01n :estimated_hours: 4.0n :remaining_hours: 4.0n ",
":date: 2018-08-22n :estimated_hours: 4.0n :remaining_hours: 0.0n "
].map(&:rstrip)
require 'yaml'
data = a[1..-1].map {|s| YAML.load(s.gsub(" ", ""))}
#=> [
# {:date=>#<Date: 2018-07-31 ((2458331j,0s,0n),+0s,2299161j)>, :estimated_hours=>4.0, :remaining_hours=>4.0},
# {:date=>#<Date: 2018-08-01 ((2458332j,0s,0n),+0s,2299161j)>, :estimated_hours=>4.0, :remaining_hours=>4.0},
# {:date=>#<Date: 2018-08-22 ((2458353j,0s,0n),+0s,2299161j)>, :estimated_hours=>4.0, :remaining_hours=>0.0}]
data.map {|h| h[:date] }
#=> [#<Date: 2018-07-31 ((2458331j,0s,0n),+0s,2299161j)>,
# #<Date: 2018-08-01 ((2458332j,0s,0n),+0s,2299161j)>,
# #<Date: 2018-08-22 ((2458353j,0s,0n),+0s,2299161j)>]
希望这有帮助
data = ["---n", ":date: 2018-07-31n :estimated_hours: 4.0n :remaining_hours: 4.0n ", ":date: 2018-08-01n :estimated_hours: 4.0n :remaining_hours: 4.0n ", ":date: 2018-08-22n :estimated_hours: 4.0n :remaining_hours: 0.0n "]
DATE_REGEX = /:date:s(.*)n/
dates = data.map do |record|
record.match(DATE_REGEX)[1] if record.match(REGEX)
end.compact