2

I take a regular expression as an input from the user and match values against that regex. But, the problem i have is that the input i receive is a string. e.g. "/abc|def/i" And i am not able to convert it to a regex object. If it try Regexp.new(string) it escapes all the characters so i get something like /\/abc|def\/i/

I was able to capture the part between the forward slashes using another regex and build a regexp object using it. For the above example, i capture "abc|def" and when i do Regexp.new("abc|def") i get /abc|def/ which is what i wanted but i need a way to also add the regexp options(e.g. 'i' in the above example) in the string to the ruby regexp object.

How can i achieve this ???

Also, there must be a easier way to achieve all of this. Any help would be greatly appreciated.

1
  • Regexp.new is only escaping the "delimiters" (/) and modifiers (i). Why not let the user drop the delimiters and enter any modifiers separately? See how they solved it at rubular.com Commented Jul 12, 2011 at 19:05

4 Answers 4

6

Here's a quick way to do it /#{my_string_pattern}/

No magic required

Sign up to request clarification or add additional context in comments.

1 Comment

@Sohan if you add \b forward slash "\" get encoded to ascii char,any suggestion ??
5

You might look into using the to_regexp gem; it doesn't use eval and it will allow you to do this:

 "/(abc|def)/i".to_regexp
 # => /(abc|def)/i

Source at https://github.com/seamusabshere/to_regexp

Comments

4

Just for fun... enjoy:

class Regexp
  def self.parse(s)
    optmap = {
      "i" => Regexp::IGNORECASE,
      "x" => Regexp::EXTENDED,
      "m" => Regexp::MULTILINE
    }

    match = s.match(/\/(.*)\/(.*)/) or raise "Invalid regexp string"
    pat = match.captures[0]
    opt_str = match.captures[1]
    opts = opt_str.split(//).map { |c| optmap[c] }.reduce { |x, n| x | n }
    Regexp.new(pat, opts)
  end
end

# because you aren't hacking Ruby until you've added a method to String...
class String
  def to_regex
    Regexp.parse(self)
  end
end

It works, too!

5 Comments

Looks like it would require options or it would fail. Otherwise, I like the way you've done it.
Nope. Works fine without options. The capture group is just an empty string, in that case.
You are right, thanks. I'll read code more carefully in the future.
missing p in Regex.parse(self)
Thanks... String::to_regex was just tacked on here in the text area :)
0

As you've suggested, I think that your method might be a way to handle it. You can clean it up a little by doing something like this...

class String
  def to_regexp(case_insensitive = false)
    str = self[\/(.*)\/,1]
    Regexp.new(str, case_insensitive)
  end
end

This is just one way to clean it up and make the functionality inherent to Strings so you don't have to worry about it.

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.