Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby regular expression using variable name

Tags:

regex

ruby

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.

like image 893
cpjolicoeur Avatar asked Feb 15 '10 19:02

cpjolicoeur


2 Answers

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" 
like image 133
Wayne Conrad Avatar answered Oct 19 '22 18:10

Wayne Conrad


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 
like image 34
FMc Avatar answered Oct 19 '22 16:10

FMc