Ruby 如何在尝试连接来自不同行的字符串时避免“nil”错误

Ruby 如何在尝试连接来自不同行的字符串时避免“nil”错误,ruby,Ruby,我有这样一个文件: 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

我有这样一个文件:

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>'
NoMethodError:nil:NilClass的未定义方法“+”
from(irb):3333:in`block in irb_binding'
发件人(irb):3325:foreach中的
发信人(irb):3325
from/usr/bin/irb:11:in`'
当我捕获包含
“risk”
的行并希望将其与存储在变量
date
中的日期连接起来时,该变量的内容是
nil

我不知道
date
何时更改为
nil
。我做错了什么?当包含单词
“risk”
的行出现时,如何存储日期以将其连接起来

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
我们首先定义两个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> 
请注意,在执行
.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"] 

是data.nil吗?打字错误?(date.nil?)也许可以删除两个否定项:
next if date.nil?
而不是
next,除非不是(date.nil?
数据是什么?
?是的,
数据.nil?
是一个打字错误,正确的是
风险.nil?
谢谢Cary。你的解决方案和往常一样有效,但在这种情况下,我不明白很多事情,呵呵。新程序{…}
是什么。。。。如何在
文件.foreach
块中的“其他”
之前定义
|行
(是相同的变量行)。。。。枚举器是什么以及它是如何工作的。。。。
p.call(line)
做什么?
Proc.new
创建一个类似于块的Proc,只是它是一个Ruby对象,因此可以传递<代码>行是每个进程的参数,类似于块变量或方法参数。作为一个变量,它也可以是
x
。两个过程
p
中的每一个都通过写入
p.call(line)
来执行,其中
line
line.strip之后保存刚刚读取的行(line
的值)被执行
enum.next
,其中
enum
是枚举数,返回两个枚举数中的一个,在两个枚举数之间交替。清楚的(另见我对问题的编辑。)你好,卡里,谢谢你的解释。我现在更了解你的代码了。现在,如果我想做一个特殊的处理,当行匹配日期时,当行匹配风险时,该怎么办?例如,如果枚举器的元素是
date\r
,则
arr定义
rrisk=/\b(?:高|低)风险\b/
prisk=Proc.new{line | line.match?r}
,并对
arr进行更改,非常感谢。它似乎与您建议的添加项配合使用。
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"]
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"]