【问题标题】:ruby multiple regexp gsub with array.injectruby 多个正则表达式 gsub 与 array.inject
【发布时间】:2016-01-25 22:32:34
【问题描述】:

我必须处理长文本并在其中使用正则表达式进行一些替换。 现在我写了以下代码:

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,但效果不一样。

有什么想法吗?

【问题讨论】:

    标签: ruby regex gsub


    【解决方案1】:

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

    我会选择 not inplace 版本的gsub

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

    以上应该可以解决问题。

    无论您是否仍想使用就地替换,您可能只是在不成功的gsub! 上返回text 本身:

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

        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
        

        【讨论】:

        • with_object 具有相反的参数顺序:|(k, v), text|
        • @mudasobwa 谢谢,会修复它
        • 你不需要空调。那是 OP 放的一些毫无意义的东西。
        • @sawa Arigatou gozaimasu !!根据您的反馈进行了一些更新。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多