2012-08-30 4 views
14

Il metodo di Ruby String#gsub fornisce un mezzo per includere l'indice della sostituzione? Ad esempio, data la seguente stringa:Ruby gsub con indice/offset?

Mi piaci, tu, tu e te.

Voglio finire con questa uscita:

mi piace you1, you2, you3 e you4.

So che posso usare \1, \2, ecc per la corrispondenza caratteri tra parentesi, ma c'è qualcosa di simile \i o \n che avrebbe fornito il numero della partita in corso?

Vale la pena ricordare che il mio vero termine non è semplice come "tu", quindi un approccio alternativo che presuppone che il termine di ricerca sia statico non sarà sufficiente.

+0

Il codice di esempio che assume '" tu "' può essere facilmente modificato dall'utente per sostituire qualsiasi target o regex necessario al suo posto. –

risposta

35

Possiamo catena with_index a gsub() per ottenere:

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

cui uscite:

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

Davvero bello. +1 – apneadiving

+2

Sia 'each_with_index' che' with_index' sono eroi non celebrati. –

+0

Ammetto che ho ignorato l'ultima! – apneadiving

3

Questo funziona, ma è brutto:

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

Cosa succede se la stringa di sostituzione include anche valori come \ 1? Come posso sostituirlo correttamente con $ 1 nella stringa corrispondente? ad es .: "ciao" .sub (/ (ello) /, "i e h \ 1") produrrà "ciao e ciao". Come posso tenere conto di queste sostituzioni all'interno del blocco? –

3

Questo è un po 'hacky, ma è possibile utilizzare una variabile che si incrementa all'interno di un blocco passato in gsub

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

stessa risposta (brutta!), Stessa ora => +1 :) – apneadiving

+0

Cosa succede se la stringa di sostituzione include anche valori come '\ 1'? Come posso sostituirlo correttamente con '$ 1' nella stringa abbinata? ad es .: '" ciao ".sub (/ (ello) /," i e h \ 1 ")' produrrà "ciao e ciao". Come posso tenere conto di queste sostituzioni all'interno del blocco? –

+0

@MattHuggins: il blocco viene chiamato per ogni gruppo. L'uso di "i e h # {match}" 'produrrà quello che stai cercando. –