我正在尝试运行vanilla regexp_replace,除了使用反向引用值动态选择替换字符串。
为了给出更多的上下文,我(在同一个表的两列中,为了简化事情)两个字符串。第一个包含占位符,如{1},{2}作为字符串文字本身的一部分;需要用第二个字符串的相应子字段替换(在用一些常量分隔符标记它之后,比如'|')。
所以,如果我们有:
Str1 ='快速褐色{1}跳过懒惰的{2}。
Str2 ='fox | dog'
我们需要结果......我相信你明白了。
在一个理想的世界中,Oracle(11g Enterprise 64位)可以让我这样做:
with x as (select 'The quick brown {1} jumps over the lazy {2}.' col1, 'fox|dog' col2 from dual)
select regexp_replace(x.col1, '({[0-9]+})', regexp_substr(x.col2,'[^|]+',1,'\1')) as result
from x
但是,第二个regexp_substr无法识别外部regexp_replace调用的反向引用并抛出ORA-17222:无效数字。
我不想创建存储过程或函数,因为我的业务案例是创建一个包含此数据的(可能是物化的)视图。我宁愿有一个可以做到这一点的单线。
查看各种论坛,Oracle可能不支持这种反向引用,因此问题标题可能有点误导 - 如果你可以指向另一种选择(不使用其他DDL),那也就是这样。我在编程方面经验丰富,但在Oracle本身并不熟悉,所以请保持温和!
有些浏览表明人们倾向于使用模糊条款和xmltables之类的模糊事物(在今天之前没有听说过)用于复杂的正则表达式拼图,但我认为可能有些东西很简单,我错过了。
答案 0 :(得分:2)
我会使用简单的PL / SQL函数 - 这只是一个循环来迭代占位符并替换变量。您也可以在SQL中使用它来定义视图。
如果你真的想要纯SQL解决方案,这里有一个使用常见的表表达式(它绝对不是很简单):
with data as (
select 1 id, 'The quick brown {1} jumps over the lazy {2} and {3}.' txt, 'fox|dog|cat' || '|' vars from dual
union all
select 2 id, 'Hello {1}' txt, 'world' || '|' vars from dual
),
recursive (id, txt, vars, i) as (
select id, txt, vars, 1 i
from data
union all
select id,
replace (txt,
'{' || i || '}',
regexp_substr(vars, '[^|]+')),
substr(vars, instr(vars, '|') + 1),
i+1
from recursive
where instr(vars, '|') > 0)
select txt
from (select txt, row_number() over (partition by id order by i desc) rn
from recursive)
where rn = 1;
答案 1 :(得分:0)
实际上,你应该尝试这个(我之前的回答忘了在regexp_substr
中捕获):
with x as (select 'The quick brown {1} jumps over the lazy {2}.' col1, 'fox|dog' col2 from dual) select regexp_replace(x.col1, '({[0-9]+})', regexp_substr(x.col2,'([^|]+)',1,1,'i',1)) as result from x;