Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Como escapar de um regexp_replace no Oracle?


Isso deve funcionar desde que você não tenha uma entrada parecida com %ABC#%ABC#
SELECT REGEXP_REPLACE( '%ABC#abc\%ABC#', '((^|[^\])(\\\\)*)%ABC#', '\1XXX' )
FROM DUAL;

Isso irá corresponder:
  • O início da string ^ ou um caractere sem barra [^\] seguido por qualquer número de pares de caracteres de barra e, finalmente, os caracteres %ABC# . Isso corresponderá a %ABC# , \\%ABC# , \\\\%ABC# e assim por diante, mas não corresponderá a \%ABC# , \\\%ABC# , \\\\\%ABC# onde há uma barra escapando do % personagem.

A substituição inclui o primeiro grupo de captura, pois a expressão pode corresponder a um caractere anterior sem barra e a pares de barras e eles precisam ser preservados na saída.

Atualizar

Isso fica um pouco complicado, mas fará correspondências repetidas:
WITH Data ( VALUE ) AS (
  SELECT '%ABC#%ABC#' FROM DUAL
)
SELECT ( SELECT LISTAGG(
                  REGEXP_REPLACE( COLUMN_VALUE, '((^|[^\])(\\\\)*)%ABC#$', '\1XXX' ),
                  NULL
                ) WITHIN GROUP ( ORDER BY NULL )
         FROM   TABLE(
                  CAST(
                    MULTISET(
                      SELECT  REGEXP_SUBSTR( d.value, '.*?(%ABC#|$)', 1, LEVEL )
                      FROM    DUAL
                      CONNECT BY LEVEL < REGEXP_COUNT( d.value, '.*?(%ABC#|$)' )
                    AS SYS.ODCIVARCHAR2LIST
                  )
                )
       ) AS Value
FROM   Data d;

Ele usa uma subconsulta correlacionada para dividir a string em substrings que terminam com %ABC# ou o final da string (este é o bit dentro da TABLE( CAST( MULTISET( ) .. ) ) ) e, em seguida, re-concatena essas substrings após realizar a substituição no final de cada substring.