使用Oracle Regexp_Replace从字符串中删除重复的嵌套短语

icomxhvb  于 2022-09-18  发布在  Java
关注(0)|答案(1)|浏览(322)

作为PL/SQL脚本的一部分,我们将设置一个名为‘V_COMMENT’的VAXIR变量:

  1. V_COMMENT := INCOMING_COMMENT || '[' || V_COMMENT || ']';

由于此语句可能为每条记录运行多次,因此我们最终将得到如下注解:

进程578[进程456[进程123]]

有一个问题,当您重新运行此脚本时,有时可能会添加重复的标记:

进程123[进程123[进程000]]

进程456[进程123[进程123]]

其中,注解被重复和嵌套。

有没有办法使用Regexp_Replace()来删除重复的标记,不管是嵌套的还是其他的?

或者另选地

有没有办法用regexp_like捕捉这些错误注解的出现

8hhllhi2

8hhllhi21#

您可以使用下面的解决方案删除重复的评论。事实上,我在pl/SQL中使用动态SQL来解决这个问题。

  1. DECLARE
  2. v_comment CLOB ;
  3. v_comment2 CLOB ;
  4. v_sql CLOB;
  5. BEGIN
  6. --V_COMMENT := INCOMING_COMMENT || '[' || V_COMMENT || ']';
  7. v_comment := 'process 456[process 123[process 123[process 456[process 000]]]]' ;
  8. v_sql := q'{
  9. with v_temp1 as (
  10. select '}'||v_comment||q'{' as comm0 from dual
  11. )
  12. , v_temp2 AS (
  13. select comm0
  14. , LEVEL lvl
  15. , regexp_count(comm0, '[^[]+') cnt
  16. , trim(rtrim( regexp_substr(comm0, '[^[]+', 1, LEVEL), ']' )) AS comm1
  17. , row_number()OVER(PARTITION BY comm0, trim(rtrim( regexp_substr(comm0, '[^[]+', 1, LEVEL), ']' )) ORDER BY LEVEL) rnb
  18. from v_temp1
  19. CONNECT BY LEVEL <= regexp_count(comm0, '[^[]+')
  20. )
  21. SELECT listagg(comm1, '[') WITHIN GROUP (ORDER BY lvl) ||
  22. LPAD(']', regexp_count(listagg(comm1, '[')WITHIN GROUP (ORDER BY lvl), '['), ']') comm2
  23. FROM v_temp2
  24. WHERE rnb = 1
  25. }'
  26. ;
  27. --dbms_output.put_line(v_sql); --test
  28. execute immediate v_sql into v_comment2
  29. ;
  30. dbms_output.put_line('input v_comment : ' ||v_comment ); --test
  31. dbms_output.put_line('output v_comment2 : '||v_comment2); --test
  32. END;
  33. /

demo : pl/sql

以下是我的解决方案中的SQL部分:

  1. with v_temp1 as (
  2. select 'process 578 [process 456 [process 123]]' comm0 from dual union all
  3. select 'process 123 [process 123 [process 000]]' from dual union ALL
  4. select 'process 456 [process 123 [process 123 [process 456 ]]]' from dual
  5. )
  6. , v_temp2 AS (
  7. select comm0
  8. , LEVEL lvl
  9. , regexp_count(comm0, '[^[]+') cnt
  10. , trim(rtrim( regexp_substr(comm0, '[^[]+', 1, LEVEL), ']' )) AS comm1
  11. , row_number()OVER(PARTITION BY comm0, trim(rtrim( regexp_substr(comm0, '[^[]+', 1, LEVEL), ']' )) ORDER BY LEVEL) rnb
  12. from v_temp1
  13. CONNECT BY LEVEL <= regexp_count(comm0, '[^[]+')
  14. /*You need to add the following two conditions when processing more than one row*/
  15. AND PRIOR comm0 = comm0
  16. AND PRIOR sys_guid() IS NOT NULL
  17. )
  18. SELECT comm0, listagg(comm1, '[') WITHIN GROUP (ORDER BY lvl) ||
  19. LPAD(']', regexp_count(listagg(comm1, '[')WITHIN GROUP (ORDER BY lvl), '['), ']') comm2
  20. FROM v_temp2
  21. WHERE rnb = 1
  22. GROUP BY comm0
  23. ;

demo : sql

展开查看全部

相关问题