我在将单词边界与 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');
运行此返回零行。有任何想法吗?
我在将单词边界与 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');
运行此返回零行。有任何想法吗?
我相信你想试试
select 1 from dual
where regexp_like ('does test work here', '(^|\s)test(\s|$)');
因为\b
没有出现在这个列表中:Perl-influenced Extensions in Oracle Regular Expressions
\s
确保测试以空格开始和结束。然而,这还不够,因为字符串test
也可能出现在被匹配字符串的开头或结尾。因此,我使用替代项(由 表示|
)^
作为字符串的开头和字符串$
的结尾。
更新(3 年后)...
碰巧,我今天需要这个功能,在我看来,更好的正则表达式是(^|\s|\W)test($|\s|\W)
(Oracle 中缺少的 \b 正则表达式特殊字符)。
可以在 Oracle 中检查整个单词的最短正则表达式是
(^|\W)test($|\W)
请参阅正则表达式演示。
细节
(^|\W)
- 一个匹配的捕获组
^
- 字符串的开始|
- 或者\W
- 一个非单词字符test
- 一个字($|\W)
- 一个匹配的捕获组
$
- 字符串结束|
- 或者\W
- 一个非单词字符。请注意,\W
匹配任何字符,但字母、数字和_
. 如果要匹配可以出现在_
(下划线)之间的单词,则需要一些不同的模式:
(^|[^[:alnum:]])test($|[^[:alnum:]])
否定括号表达式匹配除字母数字字符以外的[^[:alnum:]]
任何字符,并且 match_
将_test_
与此模式匹配。
请参阅此正则表达式演示。
一般来说,我会坚持 René 的解决方案,但当您需要匹配为零长度时例外。即您不想在开头/结尾处实际捕获非单词字符。
例如,如果我们的字符串 is test test
then(\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