2011-09-27 69 views
23

我遇到了与REGEXP_LIKE匹配工作边界的问题。按预期,以下查询返回单个行。Oracle REGEXP_LIKE和字边界

select 1 from dual 
where regexp_like('DOES TEST WORK HERE','TEST'); 

但我想匹配的单词边界以及。因此,添加“\ b”字符​​给出此查询

select 1 from dual 
where regexp_like('DOES TEST WORK HERE','\bTEST\b'); 

运行此操作会返回零行。有任何想法吗?

+0

这是奇怪的。例如,'从双重选择regexp_replace('测试工作在这里','\ bTEST \ b','X');''返回'测试工作在这里。 ..它可以工作,如果你使用'\ W',但这不同于'\ b':P – Xophmeister

回答

35

我相信你想尝试

select 1 from dual 
    where regexp_like ('does test work here', '(^|\s)test(\s|$)'); 

因为\b不会出现在此列表:http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_regexp.htm#i1007670

\s可以确保测试开始,并在空格结束。但这并不足够,因为字符串test也可能出现在匹配字符串的开头或结尾。因此,我使用替代(由|表示)^用于字符串的开始,而$用于字符串的结尾。

更新(经过3年+)... 碰巧,我今天需要这个功能,而且在我看来,甚至更好的正则表达式是(^|\s|\W)test($|\s|\W)The missing \b regular expression special character in Oracle)。

+0

谢谢你。我发现网络上有很多资源(例如http://psoug.org/snippet/Regular-Expressions--Regexp-Cheat-Sheet_856.htm),建议您可以。我实际上想匹配一个字符串的开始或结尾,或者在我的情况下是一个“非单词”字符 - 所以我将\ W替换为\ s。 –

+0

是的,似乎Oracle选择不支持'\ b',尽管这是一个相当标准的正则表达式令牌。 –

+0

Oracle的正则表达式使用不支持字边界的POSIX ERE标准(带有一些增强功能,例如反向引用)。 –

0

一般来说,我会坚持René的解决方案,例外是当你需要匹配零长度。即你不想在开始/结尾实际捕获非单词字符。

例如,如果我们的字符串是test test那么(\b)test(\b)将匹配两次,但(^|\s|\W)test($|\s|\W)只会匹配第一次出现。至少,如果您尝试使用regexp_substr,那肯定是这种情况。

SELECT regexp_substr('test test', '(^|\s|\W)test($|\s|\W)', 1, 1, 'i'), regexp_substr('test test', '(^|\s|\W)test($|\s|\W)', 1, 2, 'i') FROM dual;

返回

test |NULL