8

I want to use grep with a string as regex pattern. How can i do that?

Example:

myArray.grep(/asd/i) #Works perfectly.

But i want to prepare my statement first

searchString = '/asd/i'
myArray.grep(searchString) # Fails

How can i achieve this? I need a string prepared because this is going into a search algorithm and query is going to change on every request. Thanks.

gkaykck
  • 261
  • 1
  • 3
  • 11
  • When i said grep with string argument fails, it doesn't give an error, but it doesn't return anything either – gkaykck May 10 '12 at 12:13
  • i have a query from user, which is a string – gkaykck May 10 '12 at 12:18
  • It's not simple question. Look to [this question](http://stackoverflow.com/questions/6669425/convert-a-regular-expression-in-a-string-to-a-regexp-object-in-ruby) – Flexoid May 10 '12 at 12:25

5 Answers5

12

Regular expressions support interpolation, just like strings:

var = "hello"
re = /#{var}/i
p re #=> /hello/i
steenslag
  • 79,051
  • 16
  • 138
  • 171
  • 1
    Note that you may want to escape the value before you interpolate it, especially if it's provided by an untrusted user: `/#{Regexp.escape(user_provided_string)}/i` or `Regexp.new(Regexp.escape(user_provided_string), "i")`. This would for example treat a "." as a literal "." character and not as "any character". As a short but cryptic way to both escape a string *and* turn it into a regex, you can do `Regexp.union(user_provided_string)`. – Henrik N Aug 07 '16 at 18:55
5

Having something in quotes is not the same as the thing itself. /a/i is Regexp, "/a/i" is string. To construct a Regexp from string do this:

r = Regexp.new str
myArray.grep(r)
undur_gongor
  • 15,657
  • 5
  • 63
  • 75
Ivaylo Strandjev
  • 69,226
  • 18
  • 123
  • 176
  • Regexp.new('/asd/i') returns a regex like (?-mix:\/asd\/i)? – gkaykck May 10 '12 at 12:23
  • @gkaykck the result is not the same on my machine, still what I wanted to stress on is that a regexp is not a string. I am simply showing you how to construct a regexp from a string. In the example above if str = "/u/" then r will become /\/u\// which is not what you want, I believe you can figure out how to do what you want – Ivaylo Strandjev May 10 '12 at 12:28
1

Try this:

searchString = /asd/i
myArray.grep(searchString)
spier
  • 2,642
  • 1
  • 19
  • 16
1

Edit:

I found a better way

myString = "Hello World!"
puts "Hello World!"
puts "Enter word to search"
input_search = gets.chomp
puts "Search insensitive? y/n"

answer = gets.chomp

if answer == "y"
  ignore = "Regexp::IGNORECASE"
else
  ignore = false
end

puts myString.lines.grep(Regexp.new(input_search, ignore))

My old Answer below:

Try making it a case or if statement passing if they want insensitive search on or off, etc

myString = "Hello World!"
puts "Enter word to search"
input_search = gets.chomp
puts "Search insensitive? y/n"
case gets.chomp
  when "y"
    puts myString.lines.grep(Regexp.new(/#{input_search}/i))
  when "n"
    puts myString.lines.grep(Regexp.new(/#{input_search}/))
end
ctappy
  • 169
  • 3
  • 7
0

'/asd/i' is a String. Why not make it a Regrexp? If you need to go from String to Regexp one way to do so is by creating a new Regexp object:

>> re = Regexp.new('/asd/i')
=> /\/asd\/i/ 
>> re = Regexp.new("asd", "i")
=> /asd/i 

So perhaps,

>> str = gets.chomp #user inputs 
=> "Hello World"
re = Regexp.new(str, "i")
=> /Hello World/i

is what you're looking for.

But overall I don't think you can simply "use a string as a regexp pattern", though I'm a beginner and may be wrong about this.

Christian Meyer
  • 605
  • 8
  • 15