Ini akan berfungsi asalkan Anda tidak memiliki input yang terlihat seperti %ABC#%ABC#
SELECT REGEXP_REPLACE( '%ABC#abc\%ABC#', '((^|[^\])(\\\\)*)%ABC#', '\1XXX' )
FROM DUAL;
Ini akan cocok dengan:
- Awal string
^
atau karakter bukan garis miring[^\]
diikuti oleh sejumlah pasangan karakter garis miring lalu, akhirnya, karakter%ABC#
. Ini akan cocok dengan%ABC#
,\\%ABC#
,\\\\%ABC#
dan seterusnya tetapi tidak akan cocok dengan\%ABC#
,\\\%ABC#
,\\\\\%ABC#
di mana ada garis miring yang keluar dari%
karakter.
Penggantinya mencakup grup tangkapan pertama karena ekspresi dapat cocok dengan karakter non-garis miring sebelumnya dan pasangan garis miring, dan ini perlu dipertahankan dalam output.
Perbarui
Ini menjadi sedikit rumit tetapi akan melakukan pencocokan berulang:
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;
Ini menggunakan sub-kueri berkorelasi untuk membagi string menjadi sub-string yang diakhiri dengan %ABC#
atau akhir string (ini adalah bit di dalam TABLE( CAST( MULTISET( ) .. ) )
) dan kemudian menggabungkan kembali sub-string ini setelah melakukan penggantian di akhir setiap sub-string.