2012-08-30 19 views
14

¿El método String#gsub de Ruby proporciona un medio para incluir el índice del reemplazo? Por ejemplo, con la siguiente cadena:Ruby gsub con índice/desplazamiento?

Me gustas, tú, tú y tú.

Quiero terminar con esta salida:

me gusta you1, you2, You3 y you4.

Sé que puedo utilizar \1, \2, etc para hacer coincidir los caracteres que aparecen entre paréntesis, pero ¿hay algo como \i o \n que proporcionaría el número de la partida actual?

Vale la pena mencionar que mi término real no es tan simple como "usted", por lo que un enfoque alternativo que asume que el término de búsqueda es estático no será suficiente.

+0

Código de ejemplo suponiendo que "usted" 'se modifica fácilmente por usted para sustituir cualquier objetivo o expresión en su lugar. –

Respuesta

35

Nos puede encadenar with_index-gsub() para obtener:

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

que emite:

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

realmente agradable. +1 – apneadiving

+2

Ambos 'each_with_index' y' with_index' son héroes anónimos. –

+0

¡Admito que ignoré lo último! – apneadiving

3

Esto funciona, pero es feo:

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

¿Qué sucede si la cadena de reemplazo también incluye valores como \ 1? ¿Cómo puedo reemplazarlo adecuadamente con $ 1 en la cadena combinada? por ejemplo, "hello" .gsub (/ (ello) /, "i y h \ 1") producirá "hola y hola". ¿Cómo puedo tomar estos reemplazos en cuenta dentro del bloque? –

3

Esto es un poco hacky, pero se puede utilizar una variable que incrementas el interior de un bloque pasado a 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

misma respuesta (¡feo!), Mismo tiempo => +1 :) – apneadiving

+0

¿Qué sucede si la cadena de reemplazo también incluye valores como '\ 1'? ¿Cómo puedo reemplazarlo apropiadamente con '$ 1' en la cadena coincidente? e.g .: '" hello ".gsub (/ (ello) /," i y h \ 1 ")' producirá "hola y hola". ¿Cómo puedo tomar estos reemplazos en cuenta dentro del bloque? –

+0

@MattHuggins: se llama al bloque para cada grupo. El uso de '" i y h # {match} "' producirá lo que está buscando –

Cuestiones relacionadas