1

I have a piece of code like this:

Foo.where("name ~* '.*#{string}.*'")

Where string has both word characters and non-word characters and if some of them are not escaped I get invalid Regular Expressions errors.

So I need to get postgreslq to take string as a literal or escape the meta-characters used by the regex. Is there a way to do it instead of getting a list of all meta-characters and adding the backslash?


I have looked at both these questions but none of the answers is exactly what I'm looking for:

Here the accepted answer escapes all non-word characters. And using that with my strings I am afraid there will be weird behaviors with escaped non-word characters.

Here the answer is specific to the question and can't be used in my case.

Community
  • 1
  • 1
João Almeida
  • 4,487
  • 2
  • 19
  • 35

2 Answers2

2

I think you can just use Ruby's Regexp.escape() to espace characters in string that have a special meaning in a regular expression.

For example

> string = 'C++ /?|foo bar baz'
=> "C++ /?|"
> Regexp.escape(string)
=> "C\\+\\+\\ /\\?\\|foo\\ bar\\ baz"

With this in mind you would write

Foo.where("name ~* '.*#{Regexp.escape(string)}.*'")

Note: this is untested.

Gonçalo Ribeiro
  • 216
  • 1
  • 12
0

You could just plainly convert all characters of string to the ASCII or Unicode hex number and use the \xhh or \x{hhhh}. Should easy to code and should not have side-effects.

azt
  • 2,100
  • 16
  • 25