1

I have string like this: aa/ss/[img]aa/ss/dd[/img][img]aa/ss/dd[/img]aa/ss

I need replace this piece /ss/ with this: /WW/ but only when they are between [img] tags. result must be:

aa/ss/[img]aa/WW/dd[/img][img]aa/WW/dd[/img]aa/ss

I am trying this:

select regexp_replace('aa/ss/[img]aa/ss/dd[/img][img]aa/ss/dd[/img]aa/ss', '(\[img\].*/)ss(/.*\[\/img\])', '\1WW\2', 'g')

But this replaces just one piece, not both. I use 'g' flag buth same result.

How to do this correctly ?

Oto Shavadze
  • 40,603
  • 55
  • 152
  • 236
  • HTML and regular expressions ... http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – Erwin Brandstetter May 07 '16 at 11:39

1 Answers1

2

The problem is the "greediness" of the operators. You have repeated expressions so either ss could match the pattern once or twice -- depending on whether the middle '[/img][img] is counted as the match to the .* or to the fixed pattern.

Unfortunately, it is easier for me to diagnose the problem than fix it -- I find greediness in regular expressions to simply be confusing. But, here is a fix for your particular string. It just takes the '[' character into account:

select regexp_replace('aa/ss/[img]aa/ss/dd[/img][img]aa/ss/dd[/img]aa/ss',
                      '(\[img\][^[]*/)ss(/[^[]*\[\/img\])',
                      '\1WW\2',
                      'g')
Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786