%ABC#%ABC#のような入力がない場合、これは機能するはずです。
SELECT REGEXP_REPLACE( '%ABC#abc\%ABC#', '((^|[^\])(\\\\)*)%ABC#', '\1XXX' )
FROM DUAL;
これは次のいずれかに一致します:
- 文字列の先頭
^またはスラッシュ以外の文字[^\]続いてスラッシュ文字の任意の数のペアが続き、最後に文字%ABC#。これは%ABC#と一致します 、\\%ABC#、\\\\%ABC#などですが、\%ABC#とは一致しません 、\\\%ABC#、\\\\\%ABC#%をエスケープするスラッシュがある場所 キャラクター。
式は先行する非スラッシュ文字とスラッシュのペアに一致する可能性があり、これらは出力に保持する必要があるため、置換には最初のキャプチャグループが含まれます。
更新
これは少し複雑になりますが、繰り返し一致します:
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;
相関サブクエリを使用して、文字列を%ABC#で終わるサブ文字列に分割します。 または文字列の終わり(これはTABLE( CAST( MULTISET( ) .. ) )内のビットです。 )次に、各サブ文字列の最後で置換を実行した後、これらのサブ文字列を再連結します。