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

Sql 如何将regexp_substr()与一组分隔符字符一起使用?,sql,regex,oracle,Sql,Regex,Oracle,我有一根类似于“SERO02~~~NA_u@ERO5”的线。我需要使用分隔符~~~将其子字符串化。因此可以得到SERO02和NA_@ERO5作为结果 我创建了一个正则表达式,如下所示: select regexp_substr('SERO02~~~NA_@ERO5' ,'[^~~~]+',1,2) from dual; 它工作得很好,而且回报率很高:NA_@ERO5 但如果我将字符串改为ERO02~NA_u@ERO5,结果仍然是一样的。 但我希望表达式不返回任何内容,因为在该字符串中找不到分隔

我有一根类似于“SERO02~~~NA_u@ERO5”的线。我需要使用分隔符~~~将其子字符串化。因此可以得到SERO02和NA_@ERO5作为结果

我创建了一个正则表达式,如下所示:

select regexp_substr('SERO02~~~NA_@ERO5' ,'[^~~~]+',1,2) from dual;
它工作得很好,而且回报率很高:NA_@ERO5

但如果我将字符串改为ERO02~NA_u@ERO5,结果仍然是一样的。
但我希望表达式不返回任何内容,因为在该字符串中找不到分隔符~~。有人能帮我创造出正确的表达方式吗

无需正则表达式,只需一点逻辑即可:

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部分以获取所需内容。 即使使用regexp,要匹配字符串“~~~”,也需要准确地编写它,而不使用[];[]用于列出一组字符,因此[aaaaa]与[a]完全相同,[abc]表示“a”或“b”或“c”

对于regexp,即使没有必要,也可以采用以下方法:

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

您可以不使用正则表达式,通过一些逻辑:

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部分以获取所需内容。 即使使用regexp,要匹配字符串“~~~”,也需要准确地编写它,而不使用[];[]用于列出一组字符,因此[aaaaa]与[a]完全相同,[abc]表示“a”或“b”或“c”

对于regexp,即使没有必要,也可以采用以下方法:

substr(regexp_substr(text, '~~~.*'), 4)
[^~~~]匹配的单个字符不是方括号中插入符号后面的字符之一。由于所有这些字符都相同,因此[^~~~]与[^~]相同

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

SELECT REGEXP_SUBSTR(
         'SERO02~~~NA_@ERO5',
         '~~~(.*?)(~~~|$)',
         1,
         1,
         NULL,
         1
       )
FROM   DUAL;
它将匹配~~然后在捕获组中存储零个或多个字符圆括号表示捕获组,直到找到~~或字符串结尾。然后它将返回第一个捕获组。

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

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

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

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

以防需要所有元素。也处理空元素:

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>

以防需要所有元素。也处理空元素:

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>

[^~~]+表示匹配1个或多个字符,而不是~。等于[^~]+是的,我现在知道了。谢谢。[^~~]+表示匹配1个或多个字符,而不是~。等于[^~]+是的,我现在知道了。谢谢。用ABC~~~~DEF~~~GHI试试。你的两个查询都会返回DEF~~~GHI,它与OP在文本中描述的正则表达式不匹配。用ABC~~~~DEF~~GHI试试。你的两个查询都会返回DEF~~~GHI,它与OP在文本中描述的正则表达式不匹配。它会返回第二个外观所以,我认为这是因为'NA_u@ERO5'介于~~和字符串末尾之间。但更改“th_外观”参数不会返回其他子字符串。是否可以检索其他匹配项?它返回第二个外观作为结果,我认为这是因为'NA_@ERO5'介于~~和字符串末尾之间。但更改“th_外观”参数不会返回其他子字符串。是否可以检索其他匹配项?