如何获取某些字符之间的所有子字符串出现?

时间:2018-12-24 12:37:22

标签: sql oracle

我要获取的是列文本中某些字符之间的部分(准确地说是$$),但诀窍是这些字符可能会出现两次以上(但始终会出现两次)比必须像$$xxx$$ ... $$yyy$$的2个多),我需要分别获取它们。

当我尝试此操作时,如果模式仅出现一次,那就没问题了:

regexp_substr(txt,'\$\$(.*)\$\$',1,1,null,1)

但是可以说列文本为:$$xxx$$ ... $$yyy$$

然后它给了我:xxx$$ ... $$yyy

但是我需要两个让它们分开放置:

xxx
yyy

我做不到,怎么办?

2 个答案:

答案 0 :(得分:3)

您可以使用与第一次匹配的递归查询,然后将其从字符串中删除,以进行递归查询的下一次迭代。

假设您的表和列分别称为tbltxt

with cte(match, txt) as (
    select regexp_substr(txt,'\$\$(.*?)\$\$', 1, 1, null, 1),
           regexp_replace(txt,'\$\$(.*?)\$\$', '', 1, 1)
    from   tbl
    where  regexp_like(txt,'\$\$(.*?)\$\$') 
    union all
    select regexp_substr(txt,'\$\$(.*?)\$\$', 1, 1, null, 1),
           regexp_replace(txt,'\$\$(.*?)\$\$', '', 1, 1)
    from   cte
    where  regexp_like(txt,'\$\$(.*?)\$\$') 
)
select match from cte

答案 1 :(得分:1)

还可以使用CONNECT BY来循环遍历由双美元符号包围的元素,并返回内部的数据(第二个分组)。此方法处理NULL元素(ID 7,元素2),并且由于正则表达式从左向右移动时会消耗美元符号,因此组之间的字符不会错误匹配。

SQL> with tbl(id, txt) as (
     select 1, '$$xxx$$' from dual union all
     select 2, '$$xxx$$ ... $$yyy$$' from dual union all
     select 3, '' from dual union all
     select 4, '$$xxx$$abc$$yyy$$' from dual union all
     select 5, '$$xxx$$ ... $$yyy$$ ... $$www$$ ... $$zzz$$' from dual union all
     select 6, '$$aaa$$$$bbb$$$$ccc$$$$ddd$$' from dual union all
     select 7, '$$aaa$$$$$$$$ccc$$$$ddd$$' from dual
   )
   select id, level, regexp_substr(txt,'(\$\$(.*?)\$\$)',1,level,null,2) element
   from tbl
   connect by regexp_substr(txt,'(\$\$(.*?)\$\$)',1,level) is not null
     and prior txt = txt
     and prior sys_guid() is not null
   order by id, level;

        ID      LEVEL ELEMENT
---------- ---------- -------------------------------------------
         1          1 xxx
         2          1 xxx
         2          2 yyy
         3          1
         4          1 xxx
         4          2 yyy
         5          1 xxx
         5          2 yyy
         5          3 www
         5          4 zzz
         6          1 aaa
         6          2 bbb
         6          3 ccc
         6          4 ddd
         7          1 aaa
         7          2
         7          3 ccc
         7          4 ddd

18 rows selected.

SQL>