Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby:逐行匹配范围_Ruby_Regex_Range_Multiline - Fatal编程技术网

Ruby:逐行匹配范围

Ruby:逐行匹配范围,ruby,regex,range,multiline,Ruby,Regex,Range,Multiline,有没有办法在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

有没有办法在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
将整个文件读入内存不是一个选项,我不知道范围的块有多大

编辑:

谢谢你的回答,我得到的答案和我最初的代码基本相同。我遇到的问题是“它可以测试正确的操作数,并在它变为true的同一次计算中变为false(如在awk中),但它仍然返回true一次。”

“如果您不想让它在下一次求值之前测试正确的操作数,如在sed中,只需使用三个点(“…”)而不是两个。在所有其他方面,“…”的行为与“.”的行为类似。”

我将正确答案标记为指示我可以在发出相同呼叫时关闭“..”的答案

作为参考,我使用的代码是:

file.each_line do |line|
  if line.match(/first_line/) ... line.match(/end_line_I_care_about/)
     do_something;
  end
end

此解决方案最符合您的需要。它看起来几乎像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

括号是可选的,但可以提高可读性。

此解决方案最符合您的需要。它看起来几乎像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

括号是可选的,但可以提高可读性。

是的,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

是的,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

我并不完全清楚Perl代码的确切语义,假设您希望完全相同。Ruby确实有一些外观和工作原理类似的东西,或者可能是相同的:一个范围作为一个条件作为一个切换。您提供的代码完全符合我的设想

然而,有几个警告:

  • 即使在达到结束条件后,仍将继续读取行,直到到达文件的结尾。如果您希望结束条件接近大文件的开头,那么这可能是性能方面的考虑因素

  • 启动条件可以多次触发,将“开关”重新打开,执行
    do\u 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
    

    该代码读取文件的每一行,直到达到开始条件。然后,它从那一行开始执行任何您喜欢的处理,直到您到达一个与您的结束条件匹配的行,在这一点上它中断循环,不再从文件中读取任何行。

    我不太清楚Perl代码的确切语义,假设您希望完全相同。Ruby确实有一些外观和工作原理类似的东西,或者可能是相同的:一个范围作为一个条件作为一个切换。您提供的代码完全符合我的设想

    然而,有几个警告:

  • 即使在达到结束条件后,仍将继续读取行,直到到达文件的结尾。如果您希望结束条件接近大文件的开头,那么这可能是性能方面的考虑因素

  • 启动条件可以多次触发,将“开关”重新打开,执行
    do\u 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
    

    该代码读取文件的每一行,直到达到开始条件。然后,它从该行开始执行任何您喜欢的处理,直到达到与您的结束条件相匹配的行,在该点上它中断循环,不再从文件中读取任何行。

    您能否评论一下不鼓励使用触发器运算符?我发现它非常简洁和有用,我不明白你为什么不使用它,除非你的论点是新程序员不知道它,但是新程序员也不知道很多…你能评论一下触发器操作符被阻止了吗?我发现它非常简洁和有用,我不明白你为什么不使用它,除非你的论点是新程序员不知道它,但是新程序员也不知道很多。。。