2011-10-13 18 views
37

我得到了这个查询,并想提取括号内的值。如何在Oracle中从正则表达式中提取组?

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

然而,它给了我与括号如“[测试]”的价值。我只想要“测试”。我如何修改查询来获取它?

回答

67

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

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

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

当最后一个参数1指示要返回的捕获组的数量。

10克不会出现这个选项,但在你的情况下就可以实现同样的结果:

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

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

+0

令人惊讶的是第6个参数在Oracle官方REGEXP_SUBSTR文档中没有提及。感谢您指出它的存在。 –

14

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

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

恕我直言,这是最简单,易于记忆,更灵活,因此最好的方式来做到这一点。 –

+7

我会提醒任何人使用'REGEXP_REPLACE'来获取捕获组,如果模式不匹配,Oracle将返回整个值,而您可能需要的行为是返回'null'。例如,'REGEXP_REPLACE('abcdefghi','。* \ [(。+)\]。*','\ 1')'(模式不匹配)返回'abcdefghi'。这让我绊倒了一次。 – Jared

+0

这里的问题是Oracle正则表达式不提供返回捕获组匹配的字符串部分的函数。你可以尝试使用递归查询(select ... from tab connect by ...),但是可能会出现性能问题。 – Cyryl1972

相关问题