ruby multiple regexp gsub with array.inject

时间:2016-01-25 14:12:17

标签: ruby regex gsub

我必须使用长文本并在其中使用regexp进行替换。 现在我写了下面的代码:

text = File.read(file)
replacements = [
                [/```([\w]+)/, "\n\1>"],
                [/```\n/, "\n\n"],
                [/pattern not found/, 'sub'],
                [/pattern that should be found/, 'no sub'],
               ]
replacements.inject(text) do |text, (k,v)|
    if text =~ k
        text.gsub!(k,v)
    end
end
File.write(name', text)

如果在我的文档中找到每个正则表达式,一切正常,但如果找不到替换模式,则不会执行所有后续替换

我放了if text =~ k,但它不起作用。

有什么想法吗?

3 个答案:

答案 0 :(得分:3)

原因是如果没有替换,String#gsub!会返回nil,如果有替换,则返回结果。另一个小问题是你调用匹配两次,text =~ k的检查是多余的。

我会选择{em> not inplace 版本的gsub

result = replacements.inject(text) do |text, (k, v)|
  text.gsub(k, v)
end

以上应该可以解决问题。

您是否仍想使用就地替换,您可能只会在失败的text上返回gsub!

result = replacements.inject(text) do |text, (k, v)|
  text.gsub!(k, v) || text
end

答案 1 :(得分:2)

inject的块必须返回memo值。因此,您可能需要更改代码才能执行此操作:

replacements.inject(text) do |text, (k,v)|
    text.gsub(k,v)
end

如果if test =~ k在您的情况下失败,则该块的输出为nil - 因此,问题就出现了。

或者,您可以使用with_object

replacements.each.with_object(text) do |(k,v), text|
    text.gsub!(k,v)
end

答案 2 :(得分:2)

每次注入迭代都应该将备忘录(在您的情况下为text)返回到下一次迭代。试试这段代码:

replacements.inject(text) do |text, (k,v)|
  if text =~ k
    text.gsub!(k,v)
  end
  text
end