Oracle REGEXP_LIKE 和字边界
Posted
技术标签:
【中文标题】Oracle REGEXP_LIKE 和字边界【英文标题】:Oracle REGEXP_LIKE and word boundaries 【发布时间】:2011-11-25 22:21:18 【问题描述】:我在使用 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 regexp_replace('DOES TEST WORK HERE','\bTEST\b','X') from dual;
返回DOES TEST WORK HERE
...如果您使用\W
,它可以工作,但这与\b
不同:P
【参考方案1】:
相信你也想试试
select 1 from dual
where regexp_like ('does test work here', '(^|\s)test(\s|$)');
因为\b
未出现在此列表中:Perl-influenced Extensions in Oracle Regular Expressions
\s
确保测试以空格开始和结束。然而,这还不够,因为字符串test
也可能出现在被匹配字符串的开头或结尾。因此,我使用 alternative(由 |
表示)^
用于字符串的开头,$
用于字符串的结尾。
更新(3 年后)...
碰巧,我今天需要这个功能,在我看来,更好的正则表达式是(^|\s|\W)test($|\s|\W)
(The missing \b regular expression special character in Oracle)。
【讨论】:
谢谢。我在网上找到了很多资源(例如 psoug.org/snippet/… ),建议您可以。我实际上想匹配字符串的开头或结尾,或者在我的情况下是“非单词”字符 - 所以我用 \W 代替 \s。 是的,Oracle 似乎选择不支持\b
,尽管这是一个相当标准的正则表达式标记。
Oracle 的正则表达式使用不支持单词边界的 POSIX ERE 标准(具有一些增强功能,例如反向引用)。
在您更新的正则表达式中,\s
字符类是多余的,因为您包含了\W
(一个字符类,它是\s
的超集)。【参考方案2】:
可以在Oracle中检查整个单词的最短正则表达式是
(^|\W)test($|\W)
请参阅regex demo。
详情
(^|\W)
- 一个匹配的捕获组
^
- 字符串开头
|
- 或
\W
- 非单词字符
test
- 一句话
($|\W)
- 一个匹配的捕获组
$
- 字符串结束
|
- 或
\W
- 非单词字符。
注意\W
匹配除字母、数字和_
之外的任何字符。如果你想匹配一个可以出现在_
(下划线)之间的单词,你需要一个稍微不同的模式:
(^|[^[:alnum:]])test($|[^[:alnum:]])
[^[:alnum:]]
否定括号表达式匹配除字母数字字符以外的任何字符,并匹配 _
,因此,_test_
将与此模式匹配。
见this regex demo。
【讨论】:
【参考方案3】:一般来说,我会坚持 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
【讨论】:
但是 OP 的观点是零长度字边界 \b 在 Oracle 中不起作用。正如在其他答案中的 cmets 中所解释的那样。而且由于没有前瞻支持,我们也找不到重叠的匹配项......所以我们永远无法在字符串“some string testtest some string”中找到两个“test”匹配项。以上是关于Oracle REGEXP_LIKE 和字边界的主要内容,如果未能解决你的问题,请参考以下文章
Oracle:Oracle 8i 中 REGEXP_LIKE 函数的替代方案
oracle通过添加regexp_like将字符串连接到数字不起作用
oracle regexp_like 与 select 模式