我有一个名为“ABAAC D”的列表。我的预期结果是“ABC D”。到目前为止,我发现了网络
regexp_replace(l_user ,'([^,]+)(,[ ]*\1)+', '\1');
Run Code Online (Sandbox Code Playgroud)
表达。但这是为,分隔列表。需要做哪些修改才能使其成为空格分隔的列表。无需考虑顺序。
如果我理解得很好,您不仅需要用空格替换 ',' ,还需要以更智能的方式删除重复项。
如果我修改该表达式以使用空格而不是“,”,我会得到
select regexp_replace('A B A A C D' ,'([^ ]+)( [ ]*\1)+', '\1') from dual
Run Code Online (Sandbox Code Playgroud)
这给了'A B A C D',而不是你需要的。
获得所需结果的一种方法可能如下所示,稍微复杂一点:
with string(s) as ( select 'A B A A C D' from dual)
select listagg(case when rn = 1 then str end, ' ') within group (order by lev)
from (
select str, row_number() over (partition by str order by 1) rn, lev
from (
SELECT trim(regexp_substr(s, '[^ ]+', 1, level)) str,
level as lev
FROM string
CONNECT BY instr(s, ' ', 1, level - 1) > 0
)
)
Run Code Online (Sandbox Code Playgroud)
我的主要问题是我无法构建一个检查非相邻重复项的正则表达式,所以我需要拆分字符串,检查重复项,然后再次聚合非重复值,保持顺序。
如果您不介意结果字符串中标记的顺序,则可以简化:
with string(s) as ( select 'A B A A C D' from dual)
select listagg(str, ' ') within group (order by 1)
from (
SELECT distinct trim(regexp_substr(s, '[^ ]+', 1, level)) as str
FROM string
CONNECT BY instr(s, ' ', 1, level - 1) > 0
)
Run Code Online (Sandbox Code Playgroud)