我有一个像这样的文件:
QWWWQV27
ETYUM
2019-01-29 03:20:07
KJJD_990
RP04MMB High risk YUZZP
HHLPPD
2019-01-23 12:34:13
CDF55UHM11
UYRP566_I Low risk ABCX
我想将日期和包含单词"risk"
的下一行连接起来,并将其分配给变量。
我有以下代码。
require 'date'
File.foreach("file.txt",sep="\n") do |line|
if (DateTime.strptime(line.strip, '%Y-%m-%d %H:%M:%S') rescue nil)
date = line.strip #Here I'm storing the date in variable "date"
next
end
risk = line[/.*risk.*/]
next unless not (risk.nil?)
output = date + risk
p output
end
我收到此错误:
NoMethodError: undefined method `+' for nil:NilClass
from (irb):3333:in `block in irb_binding'
from (irb):3325:in `foreach'
from (irb):3325
from /usr/bin/irb:11:in `<main>'
当我捕获包含"risk"
的行并将其与存储在变量date
中的日期连接起来时,此变量的内容为nil
。
我不知道何时date
更改为nil
。我究竟做错了什么?包含单词"risk"
的行出现后,如何存储日期以将其串联起来?
答案 0 :(得分:1)
str =<<_
QWWWQV27
ETYUM
2019-01-29 03:20:07
KJJD_990
RP04MMB High risk YUZZP
HHLPPD
2019-01-23 12:34:13
CDF55UHM11
UYRP566_I Low risk ABCX
_
FNAME = 'temp'
File.write(FNAME, str)
#=> 144
require 'date'
我们首先定义两个proc,这两个proc都有一个参数line
,它将是文件line.strip!
之后的一行。
date_r = Proc.new { |line| DateTime.strptime(line,
'%Y-%m-%d %H:%M:%S') rescue false }
#=> #<Proc:0x00005784561a3b28@(irb):567>
risk_r = Proc.new { |line| line.match? /\brisk\b/i }
#=> #<Proc:0x00005784561c5610@(irb):569>
接下来,使用Array#cycle生成一个枚举数enum
。每次执行p = enum.next
时,两个过程date_r
和risk_r
中的一个将分配给变量p
,首先分配给变量date_r
,然后分配给risk_r
,然后是date_r
等等,直到永远。这两个过程都返回true
或false
。
enum = [date_r, risk_r].cycle
#=> #<Enumerator: [#<Proc:0x00005784561a3b28@(irb):567>,
#<Proc:0x00005784561c5610@(irb):569>]:cycle>
p = enum.next # initialize p to date_r
#=> #<Proc:0x00005784561a3b28@(irb):567>
File.foreach(FNAME).with_object([]) do |line, arr|
line.strip!
if p.call(line)
arr << line
p = enum.next
end
end.each_slice(2).map(&:join)
#=> ["2019-01-29 03:20:07RP04MMB High risk YUZZP",
# "2019-01-23 12:34:13UYRP566_I Low risk ABCX"]
请注意,在执行.each_slice(2).map(&:join)
之前,
File.foreach(FNAME).with_object([]) do |line, arr|
...
end
#=> ["2019-01-29 03:20:07", "RP04MMB High risk YUZZP",
# "2019-01-23 12:34:13", "UYRP566_I Low risk ABCX"]