Verwenden der Zeichenfolgensubstitution in Ruby

Das Aufteilen einer Zeichenfolge ist nur eine Möglichkeit, Zeichenfolgendaten zu bearbeiten. Sie können auch Ersetzungen vornehmen, um einen Teil einer Zeichenfolge durch eine andere Zeichenfolge zu ersetzen. Beispielsweise würde in einer Beispielzeichenfolge (foo, bar, baz) das Ersetzen von "foo" durch "boo" in "boo, bar, baz" ergeben. Dies und vieles mehr können Sie mit der sub und gsub Methode in der String-Klasse.

Viele Optionen für die Ruby-Substitution

Die Substitutionsmethoden gibt es in zwei Varianten. Das sub Methode ist die grundlegendste der beiden und kommt mit der geringsten Anzahl von Überraschungen. Sie ersetzt einfach die erste Instanz des angegebenen Musters durch die Ersetzung.

Wohingegen sub ersetzt nur die erste Instanz, die gsub Methode ersetzt jede Instanz des Musters durch die Ersetzung. Darüber hinaus beide sub und gsub haben sub! und gsub! Gegenstücke. Denken Sie daran, dass Methoden in Ruby, die mit einem Ausrufezeichen enden, die Variable ändern, anstatt eine geänderte Kopie zurückzugeben.

Suchen und Ersetzen

Die einfachste Verwendung der Substitutionsmethoden besteht darin, eine statische Suchzeichenfolge durch eine statische Ersatzzeichenfolge zu ersetzen. Im obigen Beispiel wurde "foo" durch "boo" ersetzt. Dies kann für das erste Vorkommen von "foo" in der Zeichenfolge mit der Taste "." Erfolgen sub Methode oder mit allen Vorkommen von "foo" mit der gsub Methode.

#! / usr / bin / env ruby
a = "foo, bar, baz"
b = a ("foo", "boo")
setzt b
$ ./1.rb
Foo, Bar, Baz
gsub $ ./1.rb
Boo, Bar, Baz

Flexible Suche

Die Suche nach statischen Zeichenfolgen kann nur so weit gehen. Schließlich werden Sie auf Fälle stoßen, in denen eine Teilmenge von Zeichenfolgen oder Zeichenfolgen mit optionalen Komponenten abgeglichen werden müssen. Die Substitutionsmethoden können natürlich regulären Ausdrücken anstelle von statischen Zeichenfolgen entsprechen. Dies ermöglicht es ihnen, viel flexibler zu sein und praktisch jedem Text zu entsprechen, den Sie sich ausdenken können.

Dieses Beispiel ist etwas realer. Stellen Sie sich eine Reihe von durch Kommas getrennten Werten vor. Diese Werte werden in ein Tabellenprogramm eingegeben, über das Sie keine Kontrolle haben (Closed Source). Das Programm, das diese Werte generiert, ist ebenfalls Closed Source, gibt jedoch einige falsch formatierte Daten aus. Einige Felder haben Leerzeichen nach dem Komma und dies führt dazu, dass das Tabulator-Programm abbricht.

Eine mögliche Lösung besteht darin, ein Ruby-Programm zu schreiben, das als "Klebstoff" oder Filter zwischen den beiden Programmen fungiert. Dieses Ruby-Programm behebt alle Probleme bei der Datenformatierung, damit der Tabulator seine Arbeit erledigen kann. Dazu ist es ganz einfach: Ersetzen Sie ein Komma, gefolgt von einer Reihe von Leerzeichen, durch ein Komma.

#! / usr / bin / env ruby
STDIN.each do | l |
l.gsub! (/, + /, ",")
setzt l
Ende
gsub $ cat data.txt
10, 20, 30
12.8, 10.4,11
gsub $ cat data.txt | ./2.rb
10,20,30
12.8,10.4,11

Flexibler Ersatz

Stellen Sie sich nun diese Situation vor. Zusätzlich zu den geringfügigen Formatierungsfehlern erzeugt das Programm, das die Daten erzeugt, Nummerndaten in wissenschaftlicher Notation. Das Tabulator-Programm versteht das nicht, daher müssen Sie es ersetzen. Offensichtlich reicht ein einfaches gsub hier nicht aus, da die Ersetzung bei jeder Ersetzung anders ausfällt.

Glücklicherweise können die Substitutionsmethoden einen Block für die Substitutionsargumente einnehmen. Bei jedem Auffinden der Suchzeichenfolge wird der mit der Suchzeichenfolge (oder dem regulären Ausdruck) übereinstimmende Text an diesen Block übergeben. Der vom Block ausgegebene Wert wird als Ersetzungszeichenfolge verwendet. In diesem Beispiel wird eine Gleitkommazahl in Form einer wissenschaftlichen Notation (z. B. 1,232e4) wird in eine normale Zahl mit einem Dezimalpunkt umgewandelt. Die Zeichenfolge wird mit in eine Zahl umgewandelt to_f, Anschließend wird die Nummer mit einer Formatzeichenfolge formatiert.

#! / usr / bin / env ruby
STDIN.each do | l |
l.gsub! (/-?\d+\.\d+e-?\d+/) do | n |
"% .3f"% n.to_f
Ende
l.gsub! (/, + /, ",")
setzt l
Ende
gsub $ cat floatdata.txt
2,215e-1, 54, 11
3.15668e6, 21, 7
gsub $ cat floatdata.txt | ./3.rb
0,222,54,11
3156680.000,21,7

Nicht vertraut mit regulären Ausdrücken?

Lassen Sie uns einen Schritt zurücktreten und diesen regulären Ausdruck betrachten. Es sieht kryptisch und kompliziert aus, ist aber sehr einfach. Wenn Sie mit regulären Ausdrücken nicht vertraut sind, können sie ziemlich kryptisch sein. Sobald Sie mit ihnen vertraut sind, sind sie jedoch eine einfache und natürliche Methode zur Beschreibung von Text. Es gibt eine Reihe von Elementen und einige der Elemente haben Quantifizierer.

Das primäre Element hier ist das \ d Zeichenklasse. Dies entspricht jeder Ziffer, den Zeichen 0 bis 9. Der Quantifizierer + wird zusammen mit der Ziffernklasse verwendet, um anzuzeigen, dass eine oder mehrere dieser Ziffern in einer Reihe übereinstimmen sollen. Sie haben drei Zifferngruppen, von denen zwei durch ein "."und der andere durch den Buchstaben getrennt"e"(für Exponenten).

Das zweite Element, das herumfliegt, ist das Minuszeichen, das das "?"quantifier. Dies bedeutet" null oder eins "dieser Elemente. Kurz gesagt, es kann negative Vorzeichen am Anfang der Zahl oder des Exponenten geben oder auch nicht.

Die beiden anderen Elemente sind die . (Punkt-) Zeichen und das e Charakter. Wenn Sie all dies kombinieren, erhalten Sie einen regulären Ausdruck (oder einen Satz von Regeln für die Übereinstimmung mit Text), der mit Zahlen in wissenschaftlicher Form übereinstimmt (z. B. 12.34e56).