如何使用范围(..)运算符查找“String”到“\ n \ n”的行?

时间:2014-01-14 16:32:01

标签: ruby

我正在尝试使用以下方法将一个文本块添加到输出文件中

File.foreach("#{options[:source]}") do |li|
    if (li['Exception:'] .. li["\n\n"]) then
            bufferBlocks.push(li)
    end
end

示例例外可能是:

#^^ log continues prior to this ^^
words .. words .. words
words .. words .. words

words .. words .. words
words .. words .. words

Exception: ERROR 50001
File:  source.cpp
Line:  221
Msg: Encountered unknown server error!

words .. words .. words
words .. words .. words

words .. words .. words
#\/  log continues below this \/

我在输出中想要的只是块:

Exception: ERROR 50001
File:  source.cpp
Line:  221
Msg: Encountered unknown server error!

2 个答案:

答案 0 :(得分:2)

我明白你要做什么。重要的是要记住每个“li”只是一行并以“\ n”结尾,所以你必须寻找“\ n”而不是“\ n \ n”。我没有尝试过,但这应该有效:

File.foreach(filename) do |li|
    if (li.start_with? "Exception:") ... (li == "\n")
        bufferBlocks.push(li)
    end
end

我找不到任何好的文档,但我认为它被称为触发器(感谢bjhaid)。如果Ruby看到在“if”部分内部使用了范围文字,那么它将非常特别地对待它。该范围的第一部分只需要是一些代码,当您希望条件(触发器)开始为真时返回true。类似地,范围的第二部分告诉Ruby何时条件应该停止为真。

顺便说一下,你可以用一个简单的局部变量完成同样的事情:

in_exception = false
File.foreach(filename) do |li|
    if in_exception
        in_exception = !(li == "\n")
    else
        in_exception = (li.start_with? "Exception:")
    end

    if in_exception
        bufferBlocks.push(li)
    end
end

答案 1 :(得分:1)

假设li是包含输入的字符串,您可以这样做:

li.scan(/Exception: .*?\nFile: .*?\nLine: .*?\nMsg: .*?$/m)

返回所有出现的数组。在您的示例中:

["Exception: ERROR 50001\nFile:  source.cpp\nLine:  221\nMsg: Encountered unknown server error!"]