有没有办法在Ruby中执行以下Perl结构?
while( my $line = $file->each_line() ) {
if($line =~ /first_line/ .. /end_line_I_care_about/) {
do_something;
# this will do something on a line per line basis on the range of the match
}
}
在ruby中会读到类似的内容:
file.each_line do |line|
if line.match(/first_line/) .. line.match(/end_line_I_care_about/)
do_something;
# this will only do it based on the first match not the range.
end
end
将整个文件读入内存不是一种选择,我不知道该范围的大块有多大。
编辑:
感谢您的回答,我得到的答案与我最初的代码基本相同。我遇到的问题是“它可以测试正确的操作数,并在同样的评估中变为错误(如在awk中),但它仍然返回true一次。”
“如果您不希望它在下一次评估之前测试正确的操作数,就像在sed中一样,只需使用三个点(”...“)而不是两个。在所有其他方面,”......“表现就像“......”一样。“
我正在标记正确答案,指出我可以在同一个电话中关闭'..'。
作为参考,我使用的代码是:
file.each_line do |line|
if line.match(/first_line/) ... line.match(/end_line_I_care_about/)
do_something;
end
end
答案 0 :(得分:5)
是的,Ruby支持触发器:
str = "aaa
ON
bbb
OFF
cccc
ON
ddd
OFF
eee"
str.each_line do |line|
puts line if line =~ /ON/..line =~ /OFF/
#puts line if line.match(/ON/)..line.match(/OFF/) #works too
end
输出:
ON
bbb
OFF
ON
ddd
OFF
答案 1 :(得分:1)
我不完全清楚Perl代码的确切语义,假设你想要完全一样。 Ruby确实具有类似的外观或工作方式,或者可能相同:作为条件的范围可用作切换。您提供的代码与我想象的完全一样。
然而,有几点需要注意:
即使达到最终条件,在您到达文件末尾之前,行仍会一直被读取。如果您希望结束条件接近大文件的开头,这可能是性能考虑因素。
可以多次触发启动条件,重新打开“开关”,执行do_something
并再次测试结束条件。如果您的条件足够具体,或者如果您想要这种行为,这可能会很好,但是需要注意这一点。
可以在调用开始条件的同时调用结束条件,只为一行提供true。
这是另一种选择:
started = false
file.each_line do |line|
started = true if line =~ /first_line_condition/
next unless started
do_something()
break if line =~ /last_line_condition/
end
该代码读取文件的每一行,直到达到开始条件。然后它会执行您喜欢的任何处理,直到您到达与您的结束条件相匹配的行,此时它会跳出循环,从文件中不再读取任何行。
答案 2 :(得分:0)
此解决方案最接近您的需求。它几乎看起来像Perl,但这个有效的Ruby(虽然触发器操作员有点气馁)。 文件是逐行读取的,它没有完全加载到内存中。
File.open("my_file.txt", "r").each_line do |line|
if (line =~ /first_line/) .. (line =~ /end_line_I_care_about/)
do_something
end
end
括号是可选的,但它们提高了可读性。