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.