Search code examples
sqlregexpostgresqlregexp-replace

Postgresql regexp_replace 'g' flag


i have string
[[good|12345]] [[bad1 [[bad2 [[bad3 [[bad4 [[bad5 [[good|12345]]

i need to kill [[ if word havent | after it.

what i do: select regexp_replace('[[good|12345]] [[bad1 [[bad2 [[bad3 [[bad4 [[bad5 [[good|12345]]', '\[\[([^\|]+?(\[\[|\Z))', '\1', 'g')

what i get: [[good|12345]] bad1 [[bad2 bad3 [[bad4 bad5 [[good|12345]]

what i want to get: [[good|12345]] bad1 bad2 bad3 bad4 bad5 [[good|12345]]

it looks like the last 2 symbols of my regexp [[ doesn't exists in next iteration of regexp


Solution

  • You should use a look-ahead instead of a group:

    select regexp_replace('[[good|12345]] [[bad1 [[bad2 [[bad3 [[bad4 [[bad5 [[good|12345]]', '\[\[([^\|]+?(?=\[\[|\Z))', '\1', 'g')
    

    See demo SQL fiddle

    enter image description here

    The (?=\[\[|\Z) look-ahead only checks the presence of [[, but does not consume the characters (i.e. matches and moves on through the string). Thus, the following [[ remain available for the next match.