Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Wie entkomme ich einem regexp_replace in Oracle?

Dies sollte funktionieren, vorausgesetzt, Sie haben keine Eingabe, die wie %ABC#%ABC# aussieht

SELECT REGEXP_REPLACE( '%ABC#abc\%ABC#', '((^|[^\])(\\\\)*)%ABC#', '\1XXX' )
FROM DUAL;

Dies entspricht entweder:

  • Der Beginn der Zeichenfolge ^ oder ein Nicht-Schrägstrich-Zeichen [^\] gefolgt von beliebig vielen Schrägstrichpaaren und schließlich die Zeichen %ABC# . Dies entspricht %ABC# , \\%ABC# , \\\\%ABC# usw., stimmt aber nicht mit \%ABC# überein , \\\%ABC# , \\\\\%ABC# wo ein Schrägstrich vor dem % steht Charakter.

Die Ersetzung umfasst die erste Erfassungsgruppe, da der Ausdruck mit einem vorangehenden Nicht-Schrägstrich-Zeichen und Schrägstrichpaaren übereinstimmen kann und diese in der Ausgabe beibehalten werden müssen.

Aktualisieren

Dies wird ein bisschen kompliziert, aber es werden wiederholte Übereinstimmungen auftreten:

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;

Es verwendet eine korrelierte Unterabfrage, um die Zeichenfolge in Unterzeichenfolgen aufzuteilen, die mit %ABC# enden oder das Ende der Zeichenkette (das ist das Bit innerhalb von TABLE( CAST( MULTISET( ) .. ) ) ) und verkettet diese Teilzeichenfolgen dann erneut, nachdem die Ersetzung am Ende jeder Teilzeichenfolge durchgeführt wurde.