Oracle REGEXP_LIKE и границы слов
У меня проблема с сопоставлением границ слов с 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');
Выполнение этого возвращает ноль строк. Есть идеи?
Ответы
Ответ 1
Я считаю, что вы хотите попробовать
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)
(Недопустимый символ\в Oracle).
Ответ 2
Самое короткое регулярное выражение, которое может проверить целое слово в Oracle
(^|\W)test($|\W)
Смотрите демо регулярных выражений.
подробности
-
(^|\W)
- группа захвата, соответствующая либо -
^
- начало строки -
|
- или же -
\W
- несловесный символ
-
test
- слово -
($|\W)
- группа захвата, соответствующая либо -
$
- конец строки -
|
- или же -
\W
- не-слово char.
Обратите внимание, что \W
соответствует любым символам, кроме букв, цифр и _
. Если вы хотите сопоставить слово, которое может появляться между _
(подчеркивания), вам нужен немного другой шаблон:
(^|[^[:alnum:]])test($|[^[:alnum:]])
Выражение с отрицанием в скобках [^[:alnum:]]
соответствует любому символу, кроме буквенно-цифровых символов, и соответствует _
, поэтому _test_
будет сопоставляться с этим шаблоном.
Смотрите это регулярное выражение.
Ответ 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