5

I'm using the following line in a postgres function:

regexp_replace(input, '[^a-z0-9\-_]+', sep, 'gi');

But I'm getting ERROR: invalid regular expression: invalid character range when I try to use it. The regex works fine in Ruby, is there a reason it'd be different in postgres?

4
  • I don't know but if I were you I will try to put the hyphen at the end of the character class or I will try to escape it twice. Commented Jul 29, 2016 at 23:02
  • 1
    I run that with no error. Maybe provide the rest of your code? Commented Jul 29, 2016 at 23:03
  • This post may be useful: stackoverflow.com/questions/12069639/postgres-regex-issue Commented Jul 29, 2016 at 23:05
  • Postgres 9.5: select regexp_replace('a_b%d-e', '[^a-z0-9\-_]+', '|', 'gi') is ok and yields a_b|d-e. Commented Jul 29, 2016 at 23:46

4 Answers 4

11

Some regexp parsers will work with a dash (-) in the middle, if after a range like you have it, but others won't. I suspect the postgres regexp parser is in the later class. The canonical way to have the dash in a regexp is to start with it, i.e. change the regexp to '[^-a-z0-9_]+' which might get it past the parser. Some regexp parsers, however, can be really fussy and not accept that, either.

I don't have a postgres to test with, but I expect they'll accept the regexp above and deal correctly. Otherwise you have to find the regexp portion of their manual and understand what it says about this.

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

2 Comments

Is the dash - really all that different than any other non-alphanum literal ? Perhaps it doesn't accept escapes at all. In reality [^a-z0-9-_] contains a valid dash literal when outside the context of a range operator.
I was just debugging PostgreSQL 14 bug that was caused by this exact issue. Moving the dash to the front of the range fixed the issue. Astonishing. Thank you
2

I had the same problem

using

\-

instead of only

-

worked to me

Comments

0

For me it worked to move the dash (-) to the end of the list

replaced [A-Za-z0-9-_.+=] with [A-Za-z0-9_.+=-] seems to work

Comments

0

[^[:digit:]\-.]

The above code will work.

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

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.