【问题标题】:How to extract group from regular expression in Oracle?如何从Oracle中的正则表达式中提取组?
【发布时间】:2011-12-07 05:09:49
【问题描述】:

我收到了这个查询,想提取括号之间的值。

select de_desc, regexp_substr(de_desc, '\[(.+)\]', 1)
from DATABASE
where col_name like '[%]';

但是,它给了我带有括号的值,例如“[TEST]”。我只想要“测试”。如何修改查询以获取?

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    REGEXP_SUBSTR 函数的第三个参数表示您要开始搜索的目标字符串(在您的示例中为de_desc)中的位置。假设在字符串的给定部分找到匹配项,它不会影响返回的内容。

    在 Oracle 11g 中,该函数有第六个参数,我认为这是您尝试使用的参数,它表示您想要返回的捕获组。正确使用的一个例子是:

    SELECT regexp_substr('abc[def]ghi', '\[(.+)\]', 1,1,NULL,1) from dual;
    

    其中最后一个参数1 表示要返回的捕获组的编号。这是描述参数的文档的link

    10g 似乎没有此选项,但在您的情况下,您可以通过以下方式获得相同的结果:

    select substr( match, 2, length(match)-2 ) from (
    SELECT regexp_substr('abc[def]ghi', '\[(.+)\]') match FROM dual
    );
    

    因为您知道匹配在开始和结束时正好有一个多余的字符。 (或者,您可以使用 RTRIM 和 LTRIM 从结果的两端删除括号。)

    【讨论】:

    • 令人惊奇的是,Oracle 的官方 REGEXP_SUBSTR 文档中没有提到第 6 个参数。感谢您指出它的存在。
    • 看起来 google 会将您带到 REGEXP_SUBSTR 的旧文档,但如果您能够找到 11g 文档,您可以看到第 6 个参数:docs.oracle.com/cd/B28359_01/server.111/b28286/…
    【解决方案2】:

    您需要进行替换并使用匹配整个字符串的正则表达式模式。

    select regexp_replace(de_desc, '.*\[(.+)\].*', '\1') from DATABASE;
    

    【讨论】:

    • 恕我直言,这是最简单、易记、更灵活的最佳方式。
    • 我会提醒任何使用 REGEXP_REPLACE 获取捕获组的人,如果模式不匹配,Oracle 将返回整个值,而您可能想要的行为是返回 null .例如,REGEXP_REPLACE ('abcdefghi', '.*\[(.+)\].*', '\1')(模式不匹配)返回abcdefghi。这让我绊倒了一次。
    • 这里的问题是Oracle正则表达式没有提供一个函数来返回捕获组匹配的字符串部分。您可以尝试使用递归查询(select ... from tab connect by ...),但要注意潜在的性能问题。
    猜你喜欢
    • 2015-05-13
    • 1970-01-01
    • 1970-01-01
    • 2017-07-06
    • 1970-01-01
    • 2018-07-29
    • 2011-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多