objetos - Expresión regular Ruby usando nombre de variable
lenguaje ruby pdf (5)
Sí
str.gsub Regexp.new(var), ''foo''
¿Es posible crear / usar un patrón de expresión regular en ruby que se base en el valor de un nombre de variable?
Por ejemplo, todos sabemos que podemos hacer lo siguiente con las cadenas de Ruby:
str = "my string"
str2 = "This is #{str}" # => "This is my string"
Me gustaría hacer lo mismo con expresiones regulares:
var = "Value"
str = "a test Value"
str.gsub( /#{var}/, ''foo'' ) # => "a test foo"
Obviamente, eso no funciona como se detalla, solo lo puse como ejemplo para mostrar lo que me gustaría hacer. Necesito regexp coincidencia basada en el valor del contenido de una variable.
¡Funciona, pero necesitas usar gsub!
o asignar el retorno a otra variable
var = "Value"
str = "a test Value"
str.gsub!( /#{var}/, ''foo'' ) # Or this: new_str = str.gsub( /#{var}/, ''foo'' )
puts str
El código que crees que no funciona, hace:
var = "Value"
str = "a test Value"
p str.gsub( /#{var}/, ''foo'' ) # => "a test foo"
Las cosas se vuelven más interesantes si var puede contener metacaracteres de expresiones regulares. Si lo hace y quiere que esos caracteres mata hagan lo que generalmente hacen en una expresión regular, entonces el mismo gsub funcionará:
var = "Value|a|test"
str = "a test Value"
str.gsub( /#{var}/, ''foo'' ) # => "foo foo foo"
Sin embargo, si su cadena de búsqueda contiene metacaracteres y no quiere que se interpreten como metacaracteres, entonces use Regexp.escape de la siguiente manera:
var = "*This*"
str = "*This* is a string"
p str.gsub( /#{Regexp.escape(var)}/, ''foo'' )
# => "foo is a string"
O simplemente dale a gsub una cadena en lugar de una expresión regular. En MRI> = 1.8.7, gsub tratará un argumento de reemplazo de cadena como una cadena simple, no como una expresión regular:
var = "*This*"
str = "*This* is a string"
p str.gsub(var, ''foo'' ) # => "foo is a string"
(Solía ser que un argumento de reemplazo de cadenas para gsub se convertía automáticamente en una expresión regular. Sé que fue así en 1.6. No recuerdo qué versión introdujo el cambio).
Como se indicó en otras respuestas, puede usar Regexp.new como alternativa a la interpolación:
var = "*This*"
str = "*This* is a string"
p str.gsub(Regexp.new(Regexp.escape(var)), ''foo'' )
# => "foo is a string"
Puede usar expresiones regulares a través de variables en ruby:
var = /Value/
str = "a test Value"
str.gsub( /#{var}/, ''foo'' )
str.gsub( Regex.new("#{var}"), ''foo'' )