Regex 正则表达式递归替换(增加缩进)
我相信这应该是可能的,我希望避免使用函数,因为它是Oracle 11g页面上的一个一次性报告,但我真的希望使用带缩进的换行符格式化以下字符串,以显示层次结构 例如:Regex 正则表达式递归替换(增加缩进),regex,oracle,oracle11g,Regex,Oracle,Oracle11g,我相信这应该是可能的,我希望避免使用函数,因为它是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 >
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
事先非常感谢这有点难看,但至少有点有效,我是如何理解这个问题的。请参阅代码中的注释
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>
如果填充在第一个参数内完成,则可以使用listagg:
with rcte (id, value, lvl, result) as (
select id, value, 1, regexp_substr(value, '(.*?)( - |$)', 1, 1, null, 1)
from your_table
union all
select id, value, lvl + 1, regexp_substr(value, '(.*?)( - |$)', 1, lvl + 1, null, 1)
from rcte
where regexp_substr(value, '(.*?)( - |$)', 1, lvl + 1, null, 1) is not null
)
select id,
listagg(case when lvl > 1 then rpad(chr(10), lvl, '>') || ' ' end || result)
within group (order by lvl) as result
from rcte
group by id
order by id;
但你也说过:
我可以做一个开始,用换行符替换-并应用CSS pre以确保它们都在一行上
因此,如果您想要一行,您可以不首先添加换行符:
with rcte (id, value, lvl, result) as (
select id, value, 1, regexp_substr(value, '(.*?)( - |$)', 1, 1, null, 1)
from your_table
union all
select id, value, lvl + 1, regexp_substr(value, '(.*?)( - |$)', 1, lvl + 1, null, 1)
from rcte
where regexp_substr(value, '(.*?)( - |$)', 1, lvl + 1, null, 1) is not null
)
select id,
listagg(case when lvl > 1 then rpad(' ', lvl, '>') || ' ' end || result)
within group (order by lvl) as result
from rcte
group by id
order by id;
您还可以在递归CTE中添加>,这可能更整洁:
with rcte (id, value, lvl, result) as (
select id, value, 1, regexp_substr(value, '(.*?)( - |$)', 1, 1, null, 1)
from your_table
union all
select id, value, lvl + 1,
rpad('>', lvl, '>') || ' ' || regexp_substr(value, '(.*?)( - |$)', 1, lvl + 1, null, 1)
from rcte
where regexp_substr(value, '(.*?)( - |$)', 1, lvl + 1, null, 1) is not null
)
select id,
listagg(result, ' ') within group (order by lvl) as result
from rcte
group by id
order by id;
我认为单独使用正则表达式是不可能做到这一点的。
with rcte (id, value, lvl, result) as (
select id, value, 1, regexp_substr(value, '(.*?)( - |$)', 1, 1, null, 1)
from your_table
union all
select id, value, lvl + 1, regexp_substr(value, '(.*?)( - |$)', 1, lvl + 1, null, 1)
from rcte
where regexp_substr(value, '(.*?)( - |$)', 1, lvl + 1, null, 1) is not null
)
select id,
listagg(case when lvl > 1 then rpad(' ', lvl, '>') || ' ' 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
with rcte (id, value, lvl, result) as (
select id, value, 1, regexp_substr(value, '(.*?)( - |$)', 1, 1, null, 1)
from your_table
union all
select id, value, lvl + 1,
rpad('>', lvl, '>') || ' ' || regexp_substr(value, '(.*?)( - |$)', 1, lvl + 1, null, 1)
from rcte
where regexp_substr(value, '(.*?)( - |$)', 1, lvl + 1, null, 1) is not null
)
select id,
listagg(result, ' ') within group (order by lvl) as result
from rcte
group by id
order by id;