3

为了获得部分文本,我在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

如果我删除该true if位,它会抱怨

范围值错误(ArgumentError)

有没有可能让它不那么笨拙,或者我应该只是这样做

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

还是有更好的方法不使用枚举?

4

3 回答 3

1

如果您逐行执行,我的偏好是这样的

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

如果您将所有内容都放在一个字符串中。我会使用拆分

mystring.split(/finish_regex/).each do |item|
  if item[/start_regex/] 
     puts item.split(/start_regex/)[-1]
  end
end
于 2011-02-21T00:39:43.210 回答
1

我认为

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

完全可以接受。操作符很强大,..但是没有被很多人使用,可能是因为他们不明白它的作用。可能它对你来说看起来很奇怪或尴尬,因为你不习惯使用它,但它会在你身上生长。在处理文本文件中的行范围时,它在 Perl 中很常见,这是我第一次遇到它,并且最终被大量使用。

我唯一不同的是添加一些括号以在视觉上将逻辑测试彼此分开,并与该行的其余部分分开:

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

Ruby(和 Perl)编码人员似乎讨厌使用括号,但我认为它们对于在视觉上分离逻辑测试很有用。对我来说,这是一个可读性,并且,通过扩展,一个维护的东西。

我能想到的唯一另一件事可能会有所帮助,那就是更改desired_portion_lines为一个数组,然后将您选择的行推到它上面。目前,使用desired_portion_lines << line附加到字符串,每次都会改变它。推动数组然后加入其元素以构建您的字符串可能会更快。

回到第一个例子。我没有对此进行测试,但我认为您可以将其简化为:

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

使用触发器遍历文件中所有行的唯一缺点是,如果启动模式可以多次出现,您将获得每个找到的块添加到desired_portion.

于 2011-02-21T03:01:42.103 回答
0

You can save three characters by replacing true if with !!() (with the flip flop belonging in between the parentheses).

于 2015-03-12T09:08:42.960 回答