181

I need to substitute the value of a string into my regular expression in Ruby. Is there an easy way to do this? For example:

foo = "0.0.0.0"
goo = "here is some other stuff 0.0.0.0" 
if goo =~ /value of foo here dynamically/
  puts "success!"
end
3
  • Are you trying to see if foo is a substring of goo? I don't think it's clear what you're asking. Commented Sep 29, 2008 at 18:52
  • If so, goo.include?(foo) is enough! Commented Sep 30, 2008 at 2:13
  • 1
    No, I wasn't trying to see if foo is a substring of goo; I also needed to do some capturing as well, hence include didn't work. Commented Sep 30, 2008 at 7:11

7 Answers 7

304

Same as string insertion.

if goo =~ /#{Regexp.quote(foo)}/
#...
Sign up to request clarification or add additional context in comments.

1 Comment

Regexp#quote is an alias of Regexp#escape cf. devdocs.io/ruby~3.2/regexp#method-c-quote
145

Note that the Regexp.quote in Jon L.'s answer is important!

if goo =~ /#{Regexp.quote(foo)}/

If you just do the "obvious" version:

if goo =~ /#{foo}/

then the periods in your match text are treated as regexp wildcards, and "0.0.0.0" will match "0a0b0c0".

Note also that if you really just want to check for a substring match, you can simply do

if goo.include?(foo)

which doesn't require an additional quoting or worrying about special characters.

4 Comments

Note that the reverse (not using .quote()) can also be useful if you're looking to construct a regex using a string.
"if you really just want to check for a substring match, you can simply do if goo.include?(foo)" => True when you're interested in checking for existence. If you're interested in replacing and already using String.gsub, then Regexp.quote may be your only option.
Just to add on to Jesse in case it isn't obvious, this means just passing the string of characters you don't need escaped to Regexp.new or Regexp.compile.
Thank you for the useful explanation of why we might want to use Regexp.quote
7

Probably Regexp.escape(foo) would be a starting point, but is there a good reason you can't use the more conventional expression-interpolation: "my stuff #{mysubstitutionvariable}"?

Also, you can just use !goo.match(foo).nil? with a literal string.

Comments

6
Regexp.compile(Regexp.escape(foo))

Comments

4

Here's a limited but useful other answer:

I discovered I that I can easily insert into a regex without using Regexp.quote or Regexp.escape if I just used single quotes on my input string: (an IP address match)

IP_REGEX = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'

my_str = "192.0.89.234 blahblah text 1.2, 1.4" # get the first ssh key 
# replace the ip, for demonstration
my_str.gsub!(/#{IP_REGEX}/,"192.0.2.0") 
puts my_str # "192.0.2.0 blahblah text 1.2, 1.4"

single quotes only interpret \\ and \'.

http://en.wikibooks.org/wiki/Ruby_Programming/Strings#Single_quotes

This helped me when i needed to use the same long portion of a regex several times. Not universal, but fits the question example, I believe.

1 Comment

i'm curious what will be thought of my post here, but i doubt it will be seen so far down here now.
2

Use Regexp.new:

if goo =~ Regexp.new(foo) # Evaluates to /0.0.0.0/

Comments

-2
foo = "0.0.0.0"
goo = "here is some other stuff 0.0.0.0" 

puts "success!" if goo =~ /#{foo}/

1 Comment

No, this will give an erroneous "true" for "here is some other stuff 070x0!0", because the dots are regexp wildcards.

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.