55

Let's say that I have an arbitrary string like

`A man + a plan * a canal : Panama!`

and I want to do a regex search for strings that are the same other than case. That is, this regular expression should match the string

`a man + A PLAN * a canal : PaNaMa!`

I take it the best approach is to backslash-escape every character with a special meaning in Ruby regular expressions, and then do Regexp.new with that string and Regexp::IGNORECASE as arguments. Is that right? Is there a tried-and-true regular expression for converting arbitrary strings into literal regular expressions?

By the way, I ultimately want to use this regular expression to do an arbitrary case-insensitive MongoDB query. So if there's another way I could be doing that, please let me know.

4 Answers 4

63

Ruby regexes can interpolate expressions in the same way that strings do, using the #{} notation. However, you do have to escape any regex special characters. For example:

input_str = "A man + a plan * a canal : Panama!"
/#{Regexp.escape input_str}/i
Sign up to request clarification or add additional context in comments.

2 Comments

This is such a great answer - it reads way better than the top voted response and feels more like Ruby to me to boot. Hope others will upvote this too..
I agree, I just upvoted this answer that now ties the accepted answer! One more vote!
58

You can use Regexp.escape to escape all the characters in the string that would otherwise be handled specially by the regexp engine.

Regexp.new(Regexp.escape("A man + a plan * a canal : Panama!"), Regexp::IGNORECASE)

or

Regexp.new(Regexp.escape("A man + a plan * a canal : Panama!"), "i")

2 Comments

Thanks, that was just what I was looking for! (Though as to MongoDB, I realized that if I'm doing this kind of search often, I should really store a downcased version of the string for performance reasons.)
Used this in a clash of code competition :D
34

If you know the regular expression you want already, you can add "i" after the expression (eg /the center cannot hold it is too late/i) to make it case insensitive.

2 Comments

Right, but that's not the question I'm asking. I have an arbitrary string (from user input), not a regular expression. If the user enters a+b, for example, I want to be able to find A+b, a+B, or A+B, not aaaaab.
I can't unify what you wrote just above with your original question. Consider revising your question?
10

A slightly more syntactic-sugary way to do this is to use the %r notation for Regexp literals:

input_str = "A man + a plan * a canal : Panama!"
%r(#{Regexp.escape(input_str)})i

Of course it comes down to personal preference.

Comments

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.