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.