Expressão regular Ruby usando nome de variável

105

É possível criar / usar um padrão de expressão regular em ruby ​​que é baseado no valor de um nome de variável?

Por exemplo, todos sabemos que podemos fazer o seguinte com strings Ruby:

str = "my string"
str2 = "This is #{str}" # => "This is my string"

Eu gostaria de fazer a mesma coisa com expressões regulares:

var = "Value"
str = "a test Value"
str.gsub( /#{var}/, 'foo' ) # => "a test foo"

Obviamente que não funciona como listado, só coloquei lá como um exemplo para mostrar o que gostaria de fazer. Eu preciso fazer a correspondência de expressão regular com base no valor do conteúdo de uma variável.

cpjolicoeur
fonte

Respostas:

184

O código que você acha que não funciona:

var = "Value"
str = "a test Value"
p str.gsub( /#{var}/, 'foo' )   # => "a test foo"

As coisas ficam mais interessantes se var puder conter metacaracteres de expressão regular. Se isso acontecer e você quiser que esses caracteres matemáticos façam o que costumam fazer em uma expressão regular, o mesmo GSUB funcionará:

var = "Value|a|test"
str = "a test Value"
str.gsub( /#{var}/, 'foo' ) # => "foo foo foo"

No entanto, se sua string de pesquisa contiver metacaracteres e você não quiser que eles sejam interpretados como metacaracteres, use Regexp.escape assim:

var = "*This*"
str = "*This* is a string"
p str.gsub( /#{Regexp.escape(var)}/, 'foo' )
# => "foo is a string"

Ou apenas dê ao gsub uma string em vez de uma expressão regular. Em MRI> = 1.8.7, gsub tratará um argumento de substituição de string como uma string simples, não uma expressão regular:

var = "*This*"
str = "*This* is a string"
p str.gsub(var, 'foo' ) # => "foo is a string"

(Antigamente, um argumento de substituição de string para gsub era automaticamente convertido em uma expressão regular. Eu sei que era assim no 1.6. Não me lembro qual versão introduziu a mudança).

Conforme observado em outras respostas, você pode usar Regexp.new como uma alternativa à interpolação:

var = "*This*"
str = "*This* is a string"
p str.gsub(Regexp.new(Regexp.escape(var)), 'foo' )
# => "foo is a string"
Wayne Conrad
fonte
4
A dica em Regexp.escape era exatamente o que eu não sabia que precisava. Obrigado!
Jeff Paquette
regxPlayerVariable = '(. *?) =. *? document \ .getElementById (# {pluginPlayeVariable})' nisto apliquei todos os itens acima, mas não estão funcionando.
SSP de
1
@SSP Pode ser bom explicar o problema em uma pergunta separada.
Wayne Conrad de
13

Funciona, mas você precisa usar gsub!ou atribuir o retorno a outra variável

var = "Value"
str = "a test Value"
str.gsub!( /#{var}/, 'foo' )  # Or this: new_str = str.gsub( /#{var}/, 'foo' )
puts str
FMc
fonte
9

sim


str.gsub Regexp.new(var), 'foo'
DigitalRoss
fonte
6

Você pode usar expressões regulares por meio de variáveis ​​em ruby:

var = /Value/
str = "a test Value"
str.gsub( /#{var}/, 'foo' )
GeekTantra
fonte
1
Não sei por que isso só tem votos negativos. Eu tentei e funciona, mesmo que você não precise das barras regex na varvariável e no primeiro parâmetro do gsub.
Tyler Collier
Acho que o objetivo das barras no gsub era mostrar que uma regex pode conter uma variável que é ela própria uma regex. A variável não precisa ser do tipo string (e, de fato, regex é melhor pelos motivos descritos na resposta de Wayne).
mahemoff