Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 正则表达式递归替换(增加缩进)_Regex_Oracle_Oracle11g - Fatal编程技术网

Regex 正则表达式递归替换(增加缩进)

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 >

我相信这应该是可能的,我希望避免使用函数,因为它是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
事先非常感谢

这有点难看,但至少有点有效,我是如何理解这个问题的。请参阅代码中的注释

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            '&gt;',
 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;