Ruby 红宝石相当于;grep-c5“;要获取比赛前后各行的上下文?

Ruby 红宝石相当于;grep-c5“;要获取比赛前后各行的上下文?,ruby,regex,grep,lines,Ruby,Regex,Grep,Lines,我已经搜索了一点,但我一定使用了错误的术语-ruby是否有办法grep一个字符串/正则表达式并返回周围的5行(上面和下面)?我知道我可以调用“grep-c5…”,甚至可以编写自己的方法,但这似乎是ruby应该有的,我只是没有使用正确的搜索词 我认为您不能向grep提供args;基于 您总是可以编写一个方法。大致如下: def new_grep(enum, pattern, lines) values = enum.grep(/pattern/).map do |x| index = e

我已经搜索了一点,但我一定使用了错误的术语-ruby是否有办法grep一个字符串/正则表达式并返回周围的5行(上面和下面)?我知道我可以调用
“grep-c5…”
,甚至可以编写自己的方法,但这似乎是ruby应该有的,我只是没有使用正确的搜索词

我认为您不能向grep提供args;基于

您总是可以编写一个方法。大致如下:

def new_grep(enum, pattern, lines)
 values = enum.grep(/pattern/).map do |x| 
   index = enum.index(x)
   i = (index - lines < 0) ? 0 : index - lines
   j = (index + lines >= enum.length) ? enum.length-1 : index + lines 
   enum[i..j]
 end
 return values.flatten.uniq
end
def new_grep(枚举、模式、行)
values=enum.grep(/pattern/).map do | x |
索引=枚举索引(x)
i=(索引线<0)?0:索引行
j=(索引+行>=枚举长度)?enum.length-1:索引+行
枚举[i..j]
结束
返回值.flatte.uniq
结束

您可以使用正则表达式执行此操作。以下是我们要搜索的字符串:

s = %{The first line
The second line
The third line
The fourth line
The fifth line
The sixth line
The seventh line
The eight line
The ninth line
The tenth line
}
EOL对我来说是“\n”,但对你来说可能是“\r\n”。我将把它固定在一个常数中:

EOL = '\n'
为了简化正则表达式,我们只定义一次“上下文”模式:

CONTEXT_LINES = 2
CONTEXT = "((?:.*#{EOL}){#{CONTEXT_LINES}})"
我们将搜索任何包含单词“fifth”的行。请注意,此正则表达式必须获取整行,包括行的结尾,才能工作:

regexp = /.*fifth.*#{EOL}/
最后,执行搜索并显示结果:

s =~ /^#{CONTEXT}(#{regexp})#{CONTEXT}/
before, match, after = $1, $2, $3
p before    # => "The third line\nThe fourth line\n"
p match     # => "The fifth line\n"
p after     # => "The sixth line\nThe seventh line\n"

谢谢你的背景grep。我想我可以补充一句,当 火柴接近顶部或底部,你仍然想要你想要的所有线条 如果没有可用的所有上下文行,您可以更改 上下文的定义如下:

CONTEXT = "((?:.*#{EOL}){0,#{CONTEXT_LINES}})"
默认情况下,匹配是贪婪的,因此如果部分或全部上下文行
可用,这就是您将要获取的。

这太棒了,谢谢!它就像一个符咒——我不得不回去重新阅读,我正在搜索的正则表达式中必须包含行尾,当我最初尝试这个时,我错过了。这个可能也有用,但我发现Wayne的答案更符合我的要求。