Sql 用另一个字符串加上相应的位置替换字符串
我想知道是否可以用另一个字符串加位置替换特定字符串,而不使用PL/SQL块循环、用户定义的函数/存储过程以及函数构造 此处:st->pos\u num 输入:Sql 用另一个字符串加上相应的位置替换字符串,sql,oracle,replace,oracle11g,oracle12c,Sql,Oracle,Replace,Oracle11g,Oracle12c,我想知道是否可以用另一个字符串加位置替换特定字符串,而不使用PL/SQL块循环、用户定义的函数/存储过程以及函数构造 此处:st->pos\u num 输入: "aa bbb st cccc dddd st eeeeeeeeeee ffff g st g h i st j k l m st" 输出: "aa bbb pos_1 cccc dddd pos_2 eeeeeeeeeee ffff g pos_3 g h i pos_4 j k l m pos_5" pos_1 post aa b
"aa bbb st cccc dddd st eeeeeeeeeee ffff g st g h i st j k l m st"
输出:
"aa bbb pos_1 cccc dddd pos_2 eeeeeeeeeee ffff g pos_3 g h i pos_4 j k l m pos_5"
pos_1 post aa bbb pos_2 cccc dddd pos_3 ee ffff g pos_4 g h i pos_5 j k l m pos_6
我觉得可以通过一行操作(可能是regex)实现它。递归cte方法
with cte(string,col,cnt,repl) as
(select string,1,regexp_count(string,'st'),regexp_replace(string,'st','pos_'||to_char(1),1,1) as repl
from test
union all
select string,col+1,cnt,regexp_replace(repl,'st','pos_'||to_char(col+1),1,1) as repl
from cte
--join it to the original table if there are multiple rows, on string column.
where col<cnt
)
cycle col set cycle to 1 default 0
select string,repl
from cte
where cnt=col
下面是一个使用递归CTE的稍微不同的解决方案。只有当st被空格或字符串的开头或结尾包围时,它才会查找st
with
inputs ( str ) as (
select 'aa bbb st sccc dddd st eee fff g st g h i st j k l m st' from dual
union all
select 'st abc st st st where st is not st' from dual
union all
select 'post st stop postal' from dual
),
r ( lvl, str, new_str ) as (
select 1, str, str
from inputs
union all
select lvl + 1, str,
regexp_replace(new_str, '( |^)st( |$)', '\1pos_' || lvl || '\2', 1, 1)
from r
where regexp_like(new_str, '( |^)(st)( |$)')
)
select str, new_str
from r
where not regexp_like(new_str, '( |^)(st)( |$)')
;
STR NEW_STR
------------------------------------------------------- ----------------------------------------------------------------------
post st stop postal post pos_1 stop postal
aa bbb st sccc dddd st eee fff g st g h i st j k l m st aa bbb pos_1 sccc dddd pos_2 eee fff g pos_3 g h i pos_4 j k l m pos_5
st abc st st st where st is not st pos_1 abc pos_2 pos_3 pos_4 where pos_5 is not pos_6
使用示范条款:
输出:
"aa bbb pos_1 cccc dddd pos_2 eeeeeeeeeee ffff g pos_3 g h i pos_4 j k l m pos_5"
pos_1 post aa bbb pos_2 cccc dddd pos_3 ee ffff g pos_4 g h i pos_5 j k l m pos_6
对可能与REGEXP_INSTR、REGEXP_REPLACE和LEVEL组合在一起。递归cte可以吗?或者您只喜欢一行:?@VamsiPrabhala请随意发布您的解决方案:首选一行优雅的解决方案,但不是必需的:您是否需要替换字符串,即使它位于较长的单词内?那么,在您的示例中,是否将输入字符串“post”替换为“popos_1”?如果不是-如果“st”仅在它是一个独立单词时才被替换,那么规则是什么?例如:如果它是一个复合词的一部分,比如“st jack”,该怎么办?@mathguy只包含完整的单词,所以st jack不应该受到影响。应更换st。+1解决方案基本正确。递归CTE导致循环冲突,可以通过向递归CTE添加cycle子句来解决。而且,不需要使用计数来切断递归;我在回答中展示了一种方法。但总的来说,解决方案是好的。我将编辑答案以添加循环子句。谢谢您的输入。将它与模型结合使用效果非常好:如果您对性能感兴趣,您可能仍然希望尝试这两种方法。示范条款的速度是出了名的慢;但是1也许你没有太多的数据,所以你不在乎;在任何情况下,唯一确定的方法是测试你的数据,而不是其他人的数据。