Я хочу преобразовать строку ___abc_[_]xyz в ...abc.\_xyz, используя регулярное выражение.
Возможно ли преобразовать _ и [_] в . и \_ соответственно в одном запросе?
Вот что я сделал до сих пор:
SELECT regexp_replace('___abc_[_]xyz','\[(.)\]','\\\1','g');
и
SELECT regexp_replace('___abc_[_]xyz','\[_\]','\_','g');
Результат обоих запросов: ___abc_\_xyz





Сделать это можно тройной заменой:
SELECT replace(replace(replace('___abc_[_]xyz','[_]','***MYREPLACE***'),'_','.'),'***MYREPLACE***','\_');
вы заменяете все [_] специальной строкой, которая не может существовать в вашем
строка и не содержащая _ (в моем примере ***MYREPLACE***)
вы заменяете все _ на .
вы заменяете все ***MYREPLACE*** на \_
Мне больше всего нравится это решение, потому что оно намного проще и быстрее, чем использование регулярного выражения.
Двойное regexp_replace может выполнить эту работу:
SELECT regexp_replace(regexp_replace('___abc_[_]xyz','(?!\[)_(?!\])','.','g'),'\[_\]','\\_','g');
regexp_replace
----------------
...abc.\_xyz
(1 row)
Первый, использующий (?!\[)_(?!\]), заменит подчеркивание НЕ между [ и ] точкой.
Второй заменит [_] на \_
Поскольку вы пытаетесь заменить жестко запрограммированным текстом, это невозможно без обратного вызова, но функции PostgreSQL
regexpне принимают функции обратного вызова в качестве аргументов замены.