我正在为Strings创建一个小的replaceParam函数,并希望能够逃避替换,e。克。
select regexp_replace('%ABC# %ABC#','%ABC#', 'XXX')
from dual;
导致
XXX XXX
但我希望能够逃脱替换,e。 G。通过在字符串前面加一个\,否则将被替换。
select regexp_replace('%ABC# \%ABC#','<themagicregexp>', 'XXX')
from dual;
应该导致
XXX \%ABC#
我尝试了不匹配的字符列表,但这不起作用。
select regexp_replace('%ABC#abc\%ABC#','<themagicregexp>', 'XXX')
from dual;
应该导致
XXXabc\%ABC#
此外,因为有人提到它:我不能使用单词边界,因为这也应该起作用:
yoyo%ABC#yoyo
我觉得这可以在一个正则表达式中完成,但我只是看不到它?
答案 0 :(得分:3)
如果您没有看起来像%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( ) .. ) )
内的位)然后重新在每个子字符串的末尾执行替换后连接这些子字符串。
答案 1 :(得分:2)
我喜欢更简单的方法:
select replace(
regexp_replace(
replace('%ABC# \%ABC#','\%','~~')
,'%ABC#', 'XXX')
,'~~','\%')
from dual;
但请注意,在这种特殊情况下不需要正则表达式 - 这也适用:
select replace(
replace(
replace('%ABC# \%ABC#','\%','~~')
,'%ABC#', 'XXX')
,'~~','\%')
from dual;