2012-04-01 14 views
2

Guten Tag!Suchen und ersetzen mehrere Wörter in einer Datei über Ruby

Ich bin ziemlich neu in Ruby und möchte eine grundlegende Such- und Ersetzungsfunktion in Ruby codieren. Wenn Sie die Funktion aufrufen, können Sie Parameter übergeben (Suchmuster, Wort ersetzen).

Dies funktioniert wie folgt: MultiEdit (pattern1, replacement1, pattern2, replacement2, ...)

Nun möchte ich meine Funktion eine Textdatei, die Suche nach pattern1 und ersetzen sie durch replacement2 lesen, suchen Sie nach pattern2 und ersetze es durch replacement2 und so weiter. Schließlich sollte der geänderte Text in eine andere Textdatei geschrieben werden.

Ich habe versucht, dies mit einer bis Schleife zu tun, aber alles was ich bekomme ist, dass nur das allererste Muster ersetzt wird, während alle folgenden Muster ignoriert werden (in diesem Beispiel wird nur Apfel durch Obst ersetzt). Ich denke, das Problem ist, dass ich den ursprünglichen, unveränderten Text immer wieder lese? Aber ich kann keine Lösung finden. Kannst du mir helfen? Es ist wichtig für mich, die Funktion so zu nennen, wie ich es tue.

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") 

Können Sie mir helfen?

Vielen Dank im Voraus!

Grüße

Antwort

5

Ihre Schleife war eine Art von innen nach außen ... tun dies stattdessen ...

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

Dies ist, was ich gesucht habe. Ich musste "enumerator" hinzufügen, weil ich eine ältere Ruby-Version verwende, aber jetzt macht es genau das, was es sollte. Vielen Dank für Ihre schnelle Antwort! –

3

Vielleicht ist der effizienteste Weg, um alle Muster für jede Zeile zu bewerten ist eine bauen Einzel regexp aus allen Suchmustern und verwendet, um die Hash-Ersatz Form von 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

Auch sehr interessanter Ansatz, um mein Problem zu beheben. Gsub ist wirklich sehr nützlich. Wird es in Zukunft öfter verwenden. Danke für Ihren Vorschlag! –

0

einfacheren und besseren Methode erb zu verwenden.

Verwandte Themen