2012-08-30 15 views
14

Bietet Rubys String#gsub Methode eine Möglichkeit, den Index des Ersatzes aufzunehmen? Zum Beispiel mit der folgenden Zeichenfolge:Ruby gsub mit Index/Offset?

Ich mag dich, du, du und du.

Ich möchte mit diesem Ausgang am Ende:

Ich mag you1, you2, you3 und you4.

Ich weiß, ich \1 verwenden kann, \2 usw. für Zeichen in Klammern passend, aber gibt es so etwas wie \i oder \n, die die Nummer des aktuellen Spiels bieten würden?

Es ist erwähnenswert, dass mein aktueller Begriff nicht so einfach ist wie "Sie", so dass ein alternativer Ansatz, der davon ausgeht, dass der Suchbegriff statisch ist, nicht ausreicht.

+0

Beispiel-Code unter der Annahme, dass "you" leicht von Ihnen geändert werden kann, um ein beliebiges benötigtes Ziel oder Regex an seiner Stelle zu ersetzen. –

Antwort

35

Wir können Kette with_index-gsub() zu erhalten:

foo = 'I like you, you, you, and you.'.gsub(/\byou\b/).with_index { |m, i| "#{m}#{1+i}" } 
puts foo 

die Ausgänge:

I like you1, you2, you3, and you4. 
+1

Wirklich nett. +1 – apneadiving

+2

Sowohl 'je_with_index' als auch' with_index' sind unbesungene Helden. –

+0

Ich gebe zu, ich ignorierte das Neueste! – apneadiving

3

Dies funktioniert, aber es ist hässlich:

n = 0; 
"I like you, you, you, and you.".gsub("you") { val = "you" + n.to_s; n+=1; val } 
=> "I like you0, you1, you2, and you3." 
+0

Was ist, wenn die Ersetzungszeichenfolge auch Werte wie \ 1 enthält? Wie kann ich das richtig mit $ 1 in der übereinstimmenden Zeichenfolge ersetzen? z. B. "Hallo" .gsub (/ (ello) /, "i und h \ 1") erzeugt "Hallo und Hallo". Wie kann ich diese Ersetzungen innerhalb des Blocks berücksichtigen? –

3

Dies ist ein wenig hacky, aber Sie können eine Variable verwenden, die Sie innerhalb eines Blocks in gsub übergeben erhöhen

source = 'I like you, you, you, and you.' 
counter = 1 
result = source.gsub(/you/) do |match| 
    res = "#{match}#{counter}" 
    counter += 1 
    res 
end 

puts result 
#=> I like you1, you2, you3, and you4. 
+1

gleiche (hässliche!) Antwort, gleiche Zeit => +1 :) – apneadiving

+0

Was ist, wenn die Ersetzungszeichenfolge auch Werte wie '\ 1' enthält? Wie kann ich das richtig durch '$ 1 'in der übereinstimmenden Zeichenkette ersetzen? Beispiel: '" Hallo ".gsub (/ (ello) /," i und h \ 1 ")' erzeugt "Hallo und Hallo". Wie kann ich diese Ersetzungen innerhalb des Blocks berücksichtigen? –

+0

@MattHuggins: Der Block wird für jede Gruppe aufgerufen. Die Verwendung von '" i und h # {match} "' erzeugt das, wonach Sie suchen. –