Die Programmiersprache Ruby (German Edition)
können nicht direkt gesetzt werden. Schließlich ist es noch wichtig, daran zu denken, dass
$~
und die davon abgeleiteten Variablen alle Thread- und methodenlokal sind. Das bedeutet, dass zwei Ruby-Threads gleichzeitig Matches durchführen können, ohne dass sie sich gegenseitig beeinflussen, und dass die Werte dieser Variablen sich nicht ändern, wenn Ihr Code eine Methode aufruft, die Pattern Matching durchführt.
9.2.4.2 Pattern Matching mit Strings
Die Klasse
String
definiert eine Reihe von Methoden, die
Regexp
-Argumente besitzen. Wenn Sie einen String mit einem regulären Ausdruck indexieren, wird der Teil des String zurückgegeben, der zum Muster passt. Wenn der
Regexp
eine Integerzahl folgt, wird das entsprechende Element von
MatchData
zurückgegeben:
"ruby123"[/\d+/] # "123"
"ruby123"[/([a-z]+)(\d+)/,1] # "ruby"
"ruby123"[/([a-z]+)(\d+)/,2] # "123"
Die Methode
slice
ist ein Synonym für den String-Indexoperator
[]
. Die Variante
slice!
liefert denselben Wert wie
slice
, löscht aber als Nebenwirkung den zurückgegebenen Substring aus dem String:
r = "ruby123"
r.slice!(/\d+/) # Gibt "123" zurück, ändert r in "ruby"
Die Methode
split
teilt einen String in ein Array aus Substrings auf, wobei ein String oder ein regulärer Ausdruck als Trenner genutzt wird:
s = "eins, zwei, drei"
s.split # ["eins,","zwei,","drei"]: Leerraum als Standardtrenner
s.split(", ") # ["eins","zwei","drei"]: fester Trenner
s.split(/\s*,\s*/) # ["eins","zwei","drei"]: Leerraum ist neben dem Komma optional
Die Methode
index
durchsucht einen String nach einem Zeichen, Substring oder Muster und gibt den Startindex zurück. Mit einem
Regexp
-Argument verhält sich die Methode so ähnlich wie der Operator
=~
, es gibt aber optional ein zweites Argument, das angibt, ab welcher Position die Suche beginnen soll. Damit können Sie auch auf den ersten Match folgende Matches finden:
text = "Hallo Welt"
pattern = /l/
first = text.index(pattern) # 2: erstes Match beginnt bei Position 2
n = Regexp.last_match.end(0) # 3: Endposition des ersten Matches
second = text.index(pattern, n) # 3: von dort aus weitersuchen
last = text.rindex(pattern) # 9: rindex sucht vom Ende aus
9.2.4.3 Suchen und Ersetzen
Die vermutlich wichtigsten
String
-Methoden, die reguläre Ausdrücke einsetzen, sind
sub
(für »substitute«) und
gsub
(für »global substitute«) und ihre verändernden Varianten
sub!
und
gsub!
. Alle diese Methoden suchen und ersetzen mit einem
Regexp
-Muster.
sub
und
sub!
ersetzen nur das erste Vorkommen des Musters.
gsub
und
gsub!
ersetzen alle Vorkommen.
sub
und
gsub
liefern einen neuen String zurück und belassen das Original unverändert.
sub!
und
gsub!
verändern den String, für den sie aufgerufen werden. Wenn Änderungen am String vorgenommen werden, liefern diese verändernden Methoden den aktualisierten String zurück. Wenn keine Veränderungen vorgenommen wurden, liefern Sie
nil
(wodurch sich die Methoden in
if
-Anweisungen und
while
-Schleifen nutzen lassen):
phone = gets # Telefonnummer einlesen
phone.sub!(/#.*$/, "") # Kommentare im Ruby-Stil entfernen
phone.gsub!(/\D/, "") # Alles außer Ziffern entfernen
Diese Methoden zum Suchen und Ersetzen müssen nicht mit regulären Ausdrücken verwendet werden, Sie können auch normale Strings als zu ersetzenden Text angeben:
text.gsub!("rails", "Rails") # Ändere überall "rails" in "Rails"
Reguläre Ausdrücke sind allerdings flexibler. Wenn Sie »rails« mit großem Wortanfang haben wollen, ohne »grails« zu verändern, nutzen Sie eine
Regexp
:
text.gsub!(/\brails\b/, "Rails") # Das Wort "Rails" überall mit einem großen R
Der Grund für diesen eigenen Unterabschnitt über die Methoden zum Suchen und Ersetzen ist, dass der neue Text kein normaler String sein muss. Stellen Sie sich vor, dass Sie einen Ersatz-String haben wollen, der von den Details des gefundenen Matches abhängt. Die Methoden zum Suchen und Ersetzen verarbeiten den Ersatz-String, bevor Sie das Ersetzen tatsächlich durchführen. Wenn der String einen Backslash enthält, gefolgt von einer einzelnen Ziffer, wird diese Ziffer als Index im Objekt
$~
verwendet und der Text aus dem
MatchData
-Objekt an Stelle des Backslash und der Ziffer genutzt. Wenn der String zum Beispiel die Escape-Sequenz
\0
enthält, wird der gesamte passende Text verwendet. Wenn der Ersatz-String eine
\1
enthält, wird der Text eingefügt, der dem ersten Unterausdruck entspricht. Der folgende Code sucht unabhängig von Groß- und Kleinschreibung
Weitere Kostenlose Bücher