2012-04-01 44 views
2

大家下午好!搜索和通过红宝石替换文件的多个单词

我非常新的Ruby和想编写一个基本的搜索和Ruby的替换功能。 当你调用该函数,你可以传递参数(搜索模式,替换单词)。

这是这样的:multiedit(模式1,replacement1,模式2,replacement2,...)

现在,我想我的函数读取一个文本文件中,搜索模式1和与replacement2取代它,搜索pattern2并将其替换为replacement2等等。最后,修改后的文本应该写入另一个文本文件。

我试图用这样做,直到循环,但我得到的是,虽然所有的下列模式被忽视只有第一个模式被替换(在这个例子中,只有苹果被替换为水果)。我认为问题在于我总是重读原始未改变的文本?但我找不出解决方案。你可以帮我吗?以我所做的方式调用函数对我来说很重要。

def multiedit(*_patterns) 

    return puts "Number of search patterns does not match number of replacement strings!" if (_patterns.length % 2 > 0) 

    f = File.open("1.txt", "r") 
    g = File.open("2.txt", "w") 

    i = 0 

    until i >= _patterns.length do 
    f.each_line {|line| 
     output = line.sub(_patterns[i], _patterns[i+1]) 
     g.puts output 
    } 
    i+=2 
    end 

    f.close 
    g.close 

end 

multiedit("apple", "fruit", "tomato", "veggie", "steak", "meat") 

你能帮我吗?

非常感谢您提前!

问候

回答

5

你的循环是一种由内而外......做到这一点,而不是...

f.each_line do |line| 
    _patterns.each_slice 2 do |a, b| 
     line.sub! a, b 
    end 
    g.puts line 
    end 
+0

这就是我一直在寻找的。必须添加require'enumerator',因为我正在运行一个较老的ruby版本,但现在它完全按照它应该做的。 非常感谢您的快速反应! – 2012-04-02 07:51:30

3

也许是最有效的方法来评估每行所有的模式是建立一个从所有的搜索模式单一的regexp并使用String#gsub

def multiedit *patterns 
    raise ArgumentError, "Number of search patterns does not match number of replacement strings!" if (_patterns.length % 2 != 0) 

    replacements = Hash[ *patterns ]. 
    regexp = Regexp.new replacements.keys.map {|k| Regexp.quote(k) }.join('|') 

    File.open("2.txt", "w") do |out| 
    IO.foreach("1.txt") do |line| 
     out.puts line.gsub regexp, replacements 
    end 
    end 
end 
+0

也很有趣的方法来解决我的问题。 gsub确实非常有用。将来会更频繁地使用它。 感谢您的建议! – 2012-04-02 07:52:52