Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to replace captured group with evaluated expression (adding an integer value to capture group)

Tags:

postgresql

I need to convert some strings with this format:

B12F34

to something like that:

Building 12 - Floor 34

but I have to add a value, say 10, to the second capture group so the new string would be as:

Building 12 - Floor 44

I can use this postgres sentence to get almost everything done, but I don't know how to add the value to the second capture group.

SELECT regexp_replace('B12F34', 'B(\d+)F(\d+)', 'Building \1 - Floor \2', 'g');

I have been searching for a way to add a value to \2 but all I have found is that I can use 'E'-modifier, and then \1 and \2 need to be \\1 and \\2:

SELECT regexp_replace('B12F34', 'B(\d+)F(\d+)', E'Building \\1 - Floor \\2', 'g')

I need some sentence like this one:

SELECT regexp_replace('B12F34', 'B(\d+)F(\d+)', E'Building \\1 - Floor \\2+10', 'g')

to get ........ Floor 44 instead of ........ Floor 34+10

like image 846
Desarrollo C.F. Avatar asked Mar 17 '16 13:03

Desarrollo C.F.


1 Answers

You can not do this in regexp alone because regexp does not support math on captured groups even if they are all numeric characters. So you have to get the group that represents the floor number, do the math and splice it back in:

SELECT regexp_replace('B12F34', 'B(\d+)F(\d+)', 'Building \1 - Floor ') ||
       ((regexp_matches('B12F34', '[0-9]+$'))[1]::int + 10)::text;

Not very efficient because of the two regexp calls. Another option is to just get the two numbers in a sub-query and assemble the string in the main query:

SELECT format('Building %L - Floor %L', m.num[1], (m.num[2])::int + 10)
FROM (
  SELECT regexp_matches('B12F34', '[0-9]+', 'g') AS num) m;
like image 173
Patrick Avatar answered Sep 20 '22 06:09

Patrick