2

Is there a way to simplify this query using only one regexp_replace?

select regexp_replace(regexp_replace('BL 081', '([^0-9.])', '', 'g'), '(^0+)', '', 'g')

the result should be 81

I'm trying to remove all non-numeric chars and leading 0's from the result

2
  • Your reference method turns 'BL 081-you sunk my battleship-097' into '81097'. Is that the desired outcome? Commented Dec 30, 2019 at 2:32
  • Yes that is just fine Commented Dec 30, 2019 at 20:00

3 Answers 3

4

You can do this by capturing the digits you want (not including any leading zeros) and removing everything else:

select regexp_replace('BL 0081', '.*?([1-9][0-9]*)$', '\1')

Output

81

Note you don't need the g flag as you are only making one replacement.

Demo on dbfiddle

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

6 Comments

When I run your dbfiddle, I get '1', not '81'. You need to make the .* non-greedy with a question mark.
@jjanes thanks for picking that up - I altered the regex slightly and didn't double check the results.
So instead of replacing everything that is not a number or leading zero with an empty string and using 'g' flag, you are selecting everything that should be in the result with the regex and are using \1 to store the match in the replacement string. Thanks, it works great
@MyRealNameIsBlaze exactly. You should also check out mikek's answer which might well perform better.
After testing it mikek's answer does run faster: Execution Time: 9.528 ms vs Execution Time: 33.374 ms
|
2

Why not just change the range from 0-9 to 1-9?

regexp_replace('BL 081', '(^[^1-9]+)', '', 'g')

3 Comments

What if the value is BL 650?
@Nick good point, then with the revision I put it in, that will give 650
Yeah, this is good although you don't need the enclosing ().
0

This pattern should do: \D+|(?<=\s)0+

\D - matches characters that are not digits
(?<=\s) - looks behind for spaces and matches leading zeros

You can use 1 fewer regexp_replace:

select regexp_replace('BL 081', '\D+|(?<=\s)0+', '', 'g')
# outputs 81

alternatively, if you are interested in the numeric value, you could use a simpler regex and then cast to an integer.

select regexp_replace('BL 081', '\D+', '')::int
# also outputs 81, but its type is int

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.