简体   繁体   English

使用红宝石触发器作为滤波器可以减少kludgy?

[英]Can using the ruby flip-flop as a filter be made less kludgy?

In order to get part of text, I'm using a true if kludge in front of a flip-flop: 为了获得部分文本,我在触发器前面使用了一个true if kludge:

desired_portion_lines = text.each_line.find_all do |line|
  true if line =~ /start_regex/ .. line =~ /finish_regex/
end
desired_portion = desired_portion_lines.join

If I remove the true if bit, it complains 如果我删除了true if位,它会抱怨

bad value for range (ArgumentError) 范围的错误值(ArgumentError)

Is it possible to make it less kludgy, or should I merely do 有可能减少它的价值,或者我应该这样做

desired_portion_lines = ""
text.each_line do |line|
  desired_portion_lines << line if line =~ /start_regex/ .. line =~ /finish_regex/
end

Or is there a better approach that doesn't use enumeration? 或者是否有更好的方法不使用枚举?

if you are doing it line by line, my preference is something like this 如果你是逐行做的,我的偏好是这样的

line =~ /finish_regex/ && p=0
line =~ /start_regex/ && p=1
puts line if p

if you have all in one string. 如果你有一个字符串。 I would use split 我会用拆分

mystring.split(/finish_regex/).each do |item|
  if item[/start_regex/] 
     puts item.split(/start_regex/)[-1]
  end
end

I think 我认为

desired_portion_lines = ""
text.each_line do |line|
  desired_portion_lines << line if line =~ /start_regex/ .. line =~ /finish_regex/
end

is perfectly acceptable. 完全可以接受。 The .. operator is very powerful, but not used by a lot of people, probably because they don't understand what it does. ..运算符非常强大,但很多人都没有使用它,可能是因为它们不了解它的作用。 Possibly it looks weird or awkward to you because you're not used to using it, but it'll grow on you. 可能它看起来很奇怪或尴尬,因为你不习惯使用它,但它会在你身上成长。 It's very common in Perl when dealing with ranges of lines in text files, which is where I first encountered it, and eventually was using it a lot. 在处理文本文件中的行范围时,它在Perl中非常常见,这是我第一次遇到它,并最终使用它很多。

The only thing I'd do differently is add some parenthesis to visually separate the logical tests from each other, and from the rest of the line: 我唯一不同的做法是添加一些括号,以便在逻辑上将逻辑测试彼此分开,并从行的其余部分:

desired_portion_lines = ""
text.each_line do |line|
  desired_portion_lines << line if ( (line =~ /start_regex/) .. (line =~ /finish_regex/) )
end

Ruby (and Perl) coders seem to abhor using parenthesis, but I consider them useful for visually separating the logic tests. Ruby(和Per​​l)编码器似乎厌恶使用括号,但我认为它们对于在视觉上分离逻辑测试很有用。 For me it's a readability and, by extension, a maintenance thing. 对我来说,这是一个可读性,并且,通过扩展,它是一个维护的东西。

The only other thing I can think of that might help, would be to change desired_portion_lines to an array, and push your selected lines onto it. 我能想到的另一件事可能会有所帮助,那就是将desired_portion_lines更改为一个数组,然后将选定的行推到它上面。 Currently, using desired_portion_lines << line appends to the string, mutating it each time. 目前,使用desired_portion_lines << line追加到字符串,每次都要改变它。 It might be faster pushing on the array then joining its elements afterward to build your string. 推送数组然后加入其元素以构建字符串可能会更快。

Back to the first example. 回到第一个例子。 I didn't test this but I think you can simplify it to: 我没有对此进行测试,但我认为您可以将其简化为:

desired_portion = text.each_line.find_all { |line| line =~ /start_regex/ .. line =~ /finish_regex/ }.join

The only downside to iterating over all lines in a file using the flip-flop, is that if the start-pattern can occur multiple times, you'll get each found block added to desired_portion . 使用触发器迭代文件中所有行的唯一缺点是,如果启动模式可以多次出现,则会将每个找到的块添加到desired_portion

true if使用!!() (触发器属于括号之间!!() ,则可以通过替换true if来保存三个字符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM