2011-05-13 15 views
5

que tienen una gran cantidad de documentos que se ven así:¿Cómo busco, incremento y reemplazo de subcadenas enteras en una cadena de Ruby?

foo_1 foo_2 

foo_3 

bar_1 foo_4 ... 

y quiero convertirlos mediante la adopción de todas las instancias de foo_[X] y la sustitución de cada uno de ellos con foo_[X+1]. En este ejemplo:

foo_2 foo_3 

foo_4 

bar_1 foo_5 ... 

¿Puedo hacer esto con gsub y un bloque? Si no, ¿cuál es el enfoque más limpio? Realmente estoy buscando una solución elegante porque siempre puedo forzarla brutalmente, pero creo que hay algunos trucos recíprocos que vale la pena aprender.

Respuesta

4

No sé Ruby (en absoluto), pero algo similar a esto debería funcionar:

"foo_1 foo_2".gsub(/(foo_)(\d+)/) {|not_needed| $1 + ($2.to_i + 1).to_s} 

LE: En realidad me hizo que funcione: http://codepad.org/Z5ThOvTr

+0

Gracias! No consideré la coincidencia (foo_) y la reutilicé en el bloque. –

+1

Puede omitir '| not_needed |' por completo. –

+0

@Wayne Oh, OK. Pero lo dejaré así para mostrar que está disponible pero no usado. –

4

Si lo que desea los números siguientes loquesea _ sean cambiados

str.gsub(/(?<=foo_)\d+/) {|num| num.to_i+1} 

Nota: Look-behinds solo funcionará en versiones o Ruby> = 1.9.

+3

En realidad, mirar hacia atrás _puede_ funcionar si su versión de Ruby es> = 1.9. 1.9 agrega algunas características nuevas interesantes y un maravilloso motor de expresiones regulares llamado Oniguruma (que también es usado por PHP5 mb regex). –

+0

@Phrogz. Desafortunadamente, la mayoría de las personas todavía usan Ruby 1.8, que puede manejar las aseveraciones de previsión, pero no de retrospectiva ... –

+0

Quité mi comentario ya que claramente no tengo suficiente información sobre Ruby para hacer un comentario informado. Sabiendo que regular-expressions.info es una fuente confiable, erróneamente, asumí que estaba actualizada. También tal vez debería agregar un comentario en la respuesta para especificar para qué versión funciona su código. –

2

aún más simple es sólo con .Next

"foo_1".next #=> foo_2 
"bar_1 foo_1".next #=> bar_1 foo_2 

Por lo tanto, se puede simplificar su expresión regular y bloquear así como

"bar_1 foo_2".gsub(/\bfoo_\d+\b/) {|f| f.next } 
Cuestiones relacionadas