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"]