【问题标题】:Oracle regexp_replace to pick out pattern matching groupsOracle regexp_replace 挑选出模式匹配组
【发布时间】:2021-09-09 00:13:56
【问题描述】:

我正在努力从 Oracle 11g 中的字符串中获取与模式匹配的组。 它几乎可以工作,但我不明白为什么最后的不匹配部分仍然存在:

select regexp_replace('ST1_12 text1, KG32_1 text2, VI7_08 text3','.*?(\w+\d+_\d+).*','\1,') c1
from dual

当前结果:ST1_12,KG32_1,VI7_08, text3

预期结果:ST1_12,KG32_1,VI7_08

在我看来,结尾部分不包含在搜索模式中,只是简单地粘在了末尾,但是如何摆脱它呢?

【问题讨论】:

    标签: oracle regexp-replace


    【解决方案1】:

    匹配第三组后,它开始从 text3 中寻找下一个匹配;尾随 .* 被有效忽略。对于较早的组,这就是您想要的 - 否则第一组的尾随 .* 将包含字符串的其余部分,您将丢失其他组。当它从 text3 开始时,它找不到另一个匹配项,因此返回原始值(当时)。

    如果值始终以逗号分隔,那么您可以在匹配项中包含逗号或字符串结尾锚点,以使其包含剩余的文本(直到空格),但不在 \1 中:

    select regexp_replace('ST1_12 text1, KG32_1 text2, VI7_08 text3','.*?(\w+\d+_\d+).*(,|$)', '\1,') c1
    from dual;
    
    ST1_12,KG32_1,VI7_08,
    

    您可以使用修剪功能去除尾随逗号:

    select rtrim(regexp_replace('ST1_12 text1, KG32_1 text2, VI7_08 text3','.*?(\w+\d+_\d+).*(,|$)','\1,', 1, 0, null),
      ',') as c1
    from dual;
    
    ST1_12,KG32_1,VI7_08
    

    另一个不依赖于现有逗号的选项是将字符串拆分为多个值:

    select regexp_substr('ST1_12 text1, KG32_1 text2, VI7_08 text3', '(\w+\d+_\d+)', 1, level, null, 1) as c1
    from dual
    connect by level <= regexp_count('ST1_12 text1, KG32_1 text2, VI7_08 text3', '(\w+\d+_\d+)');
    
    ST1_12
    KG32_1
    VI7_08
    

    然后将它们重新聚合在一起:

    select listagg(
      regexp_substr('ST1_12 text1, KG32_1 text2, VI7_08 text3', '(\w+\d+_\d+)', 1, level, null, 1),
      ',') within group (order by level) as c1
    from dual
    connect by level <= regexp_count('ST1_12 text1, KG32_1 text2, VI7_08 text3', '(\w+\d+_\d+)');
    
    ST1_12,KG32_1,VI7_08
    

    db<>fiddle

    【讨论】:

    • 非常感谢 Alex 的详尽解释,非常感谢!
    猜你喜欢
    • 2019-06-25
    • 2018-08-29
    • 2014-10-05
    • 2018-07-19
    • 1970-01-01
    • 2013-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多