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

Posted

技术标签:

【中文标题】如何将 regexp_substr() 与一组分隔符一起使用?【英文标题】:How to use regexp_substr() with group of delimiter characters? 【发布时间】:2016-06-09 11:49:55 【问题描述】:

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

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

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

它运行良好并返回:NA_@ERO5

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

【问题讨论】:

[^~~~]+ 表示匹配除 ~ 之外的 1 个或多个字符。它等于[^~]+ 是的,我现在明白了。谢谢。 【参考方案1】:

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

您可以使用以下方式匹配它:

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

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

【讨论】:

它返回第二次出现作为结果,我认为这是因为'NA_@ERO5'在~~~和字符串结尾之间。但是更改 'th_appearance ' 参数不会返回其他子字符串。是否可以检索其他匹配项?【参考方案2】:

你可以不用正则表达式,用一点逻辑:

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)

【讨论】:

ABC~~~DEF~~~GHI试试,你的两个查询都将返回DEF~~~GHI,这与OP在文本中描述的正则表达式匹配不同。【参考方案3】:

如果您想要所有元素。也处理 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>

【讨论】:

以上是关于如何将 regexp_substr() 与一组分隔符一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate:如何映射与一组复杂对象的一对多关联?

将结构与一组模式匹配

找到与一组数组相交的最小数组

如何识别与一组数据相关的选定 ComboBox 项?

使用 regexp_substr 在 Oracle 中按空格和字符拆分字符串作为分隔符

Oracle REGEXP_SUBSTR |获取两个分隔符之间的字符串