如何将regexp_substr()与分隔符字符组一起使用?

时间:2016-06-09 11:49:56

标签: sql regex oracle

我有一个类似'SERO02 ~~~ NA_ @ ERO5'的字符串。我需要使用分隔符 ~~~ 对其进行子字符串。因此可以得到SERO02和NA_ @ ERO5。

我创建了这样的正则表达式:

select regexp_substr('SERO02~~~NA_@ERO5' ,'[^~~~]+',1,2) from dual;

工作正常并返回:NA_ @ ERO5

但如果我将字符串更改为ERO02~NA_ @ ERO5,结果仍然相同。 但我希望表达式不返回任何内容,因为在该字符串中找不到分隔符 ~~~ 。有人可以帮助我创建正确的表达方式吗?

3 个答案:

答案 0 :(得分:2)

[^~~~]匹配单个字符,该字符不是方括号中插入符号后面的字符之一。由于所有这些字符都相同,因此[^~~~][^~]相同。

您可以使用以下方式进行匹配:

SELECT REGEXP_SUBSTR(
         'SERO02~~~NA_@ERO5',
         '~~~(.*?)(~~~|$)',
         1,
         1,
         NULL,
         1
       )
FROM   DUAL;

匹配~~~然后在捕获组中存储零个或多个字符(圆括号()表示捕获组),直到找到~~~或结束 - 的字符串。然后它将返回第一个捕获组。

答案 1 :(得分:1)

你可以在没有正则表达式的情况下做一些逻辑:

with test(text) as ( select 'SERO02~~~NA_@ERO5' from dual)
select case
         when instr(text, '~~~') != 0 then
            substr(text, instr(text, '~~~') + 3)
         else
            null
         end
from test

这将在'~~~'之后给出字符串的一部分(如果存在),否则为null。 您可以编辑ELSE部分,以便在输入字符串不包含'~~~'时获得所需内容。 即使使用正则表达式来匹配字符串'~~~',您也需要准确地编写它,而不是[]; []用于列出一组字符,因此[aaaaa][a]完全相同,而[abc]表示'a' OR 'b' OR 'c'

使用正则表达式,即使没有必要,也可以采用以下方法:

substr(regexp_substr(text, '~~~.*'), 4)

答案 2 :(得分:0)

如果您想要所有元素。处理NULL元素:

SQL> with tbl(str) as (
      select 'SERO02~~~NA_@ERO5' from dual
    )
    select regexp_substr(str, '(.*?)(~~~|$)', 1, level, null, 1) element
    from tbl
    connect by  level <= regexp_count(str, '~~~') + 1;

ELEMENT
-----------------
SERO02
NA_@ERO5

SQL>