116

Is is possible to create/use a regular expression pattern in ruby that is based on the value of a variable name?

For instance, we all know we can do the following with Ruby strings:

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

I'd like to do the same thing with regular expressions:

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

Obviously that doesn't work as listed, I only put it there as an example to show what I'd like to do. I need to regexp match based on the value of a variable's content.

5 Answers 5

207

The code you think doesn't work, does:

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

Things get more interesting if var can contain regular expression meta-characters. If it does and you want those matacharacters to do what they usually do in a regular expression, then the same gsub will work:

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

However, if your search string contains metacharacters and you do not want them interpreted as metacharacters, then use Regexp.escape like this:

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

Or just give gsub a string instead of a regular expression. In MRI >= 1.8.7, gsub will treat a string replacement argument as a plain string, not a regular expression:

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

(It used to be that a string replacement argument to gsub was automatically converted to a regular expression. I know it was that way in 1.6. I don't recall which version introduced the change).

As noted in other answers, you can use Regexp.new as an alternative to interpolation:

var = "*This*"
str = "*This* is a string"
p str.gsub(Regexp.new(Regexp.escape(var)), 'foo' )
# => "foo is a string"
Sign up to request clarification or add additional context in comments.

3 Comments

The hint on Regexp.escape was just what I didn't know I needed. Thanks!
regxPlayerVariable = '(.*?)=.*?document\.getElementById(#{pluginPlayeVariable})' in this i applied all above but these are not working.
@SSP It might be good to explain the trouble in a separate question.
13

It works, but you need to use gsub! or assign the return to another variable

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

Comments

11

Yes


str.gsub Regexp.new(var), 'foo'

Comments

7

You can use regular expressions through variables in ruby:

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

2 Comments

I'm not sure why this only has downvotes. I tried it and it works, even though you don't need the regex slashes in both the var variable and gsub's first parameter.
I think the point of the slashes in gsub was to show that a regex can contain a variable which is itself a regex. The variable doesn't have to be string type (and in fact, regex is better for reasons outlined in Wayne's answer).
3
str.gsub( Regexp.new("#{var}"), 'foo' )

2 Comments

I think it's Regexp

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.