如何解决正则表达式递归替换增加缩进
我确定应该可以,并且我想避免使用函数,因为它是页面上的一次性报告(Oracle 11g),但是我真的很想用缩进的换行符格式化以下字符串随后每次替换“-”以显示层次结构
例如:
This is the base level - This is level 2 - And this is the second
因此,我可以开始并用换行符替换“-”并应用CSS pre以确保它们全部在一行上
但理想情况下,我想要这样:
This is the base level
> This is level 2
>> And this is the second
非常感谢
解决方法
这有点像 ugly ,但是有点起作用(至少,我对这个问题的理解)。查看代码中的注释。
SQL> WITH test (col)
2 -- Sample string
3 AS (SELECT 'This is the base level - This is level 2 - And this is the second'
4 FROM DUAL),5 -- Split it to rows (minus sign is a delimiter)
6 temp
7 AS ( SELECT LEVEL lvl,8 TRIM (REGEXP_SUBSTR (col,9 '[^-]+',10 1,11 LEVEL))
12 val
13 FROM test
14 CONNECT BY LEVEL <= REGEXP_COUNT (col,'-') + 1)
15 -- join it back,using '>' along with CHR(10) as delimiter
16 SELECT REPLACE (
17 XMLAGG (XMLELEMENT (e,LPAD ('>',lvl - 1,'>') || val || CHR (10)) ORDER BY
18 lvl).EXTRACT (
19 '//text()'),20 '>',21 '>')
22 result
23 FROM temp;
RESULT
--------------------------------------------------------------------------------
This is the base level
>This is level 2
>>And this is the second
SQL>
如果您问“为什么XMLAGG
而不是LISTAGG
”,那是因为
16 SELECT LISTAGG (val,'>')) WITHIN GROUP (ORDER BY lvl)
17 FROM temp;
SELECT LISTAGG (val,'>')) WITHIN GROUP (ORDER BY lvl)
*
ERROR at line 16:
ORA-30496: Argument should be a constant.
,
如果在第一个参数内完成填充,则可以使用listagg
:
with rcte (id,value,lvl,result) as (
select id,1,regexp_substr(value,'(.*?)( - |$)',null,1)
from your_table
union all
select id,lvl + 1,1)
from rcte
where regexp_substr(value,1) is not null
)
select id,listagg(case when lvl > 1 then rpad(chr(10),'>') || ' ' end || result)
within group (order by lvl) as result
from rcte
group by id
order by id;
ID | RESULT
-: | :--------------------------------------------------------------------------------
1 | This is the base level
> This is level 2
>> And this is the second
2 | Base only
但是你也说过
我可以开始并用换行符替换“-”并应用CSS pre以确保它们全部在一行上
因此,如果您只想换一行,就不能只添加换行符:
with rcte (id,listagg(case when lvl > 1 then rpad(' ','>') || ' ' end || result)
within group (order by lvl) as result
from rcte
group by id
order by id;
ID | RESULT
-: | :-------------------------------------------------------------------------------
1 | This is the base level > This is level 2 >> And this is the second
2 | Base only
您还可以在递归CTE中添加>,这可能会更整洁:
with rcte (id,rpad('>','>') || ' ' || regexp_substr(value,listagg(result,' ') within group (order by lvl) as result
from rcte
group by id
order by id;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。