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','bTESTb');

запуск этого возвращает ноль строк. Есть идеи?

3 ответов


Я считаю, что вы хотите попробовать

 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) (отсутствует специальный символ регулярного выражения \b в Oracle).


В общем, я бы придерживался решения Рене, за исключением случаев, когда вам нужно, чтобы матч был нулевой длины. т. е. вы не хотите фактически захватывать символ не-слова в начале/конце.

например, если наша строка 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


самое короткое регулярное выражение, которое может проверить целое слово в Oracle, -

(^|\W)test($|\W)

посмотреть regex demo.

подробности

  • (^|\W) - группа захвата, соответствующая либо
    • ^ - начало строки
    • | или
    • \W - не-слово char
  • test - слово
  • ($|\W) - группа захвата соответствие либо
    • $ - конец строки
    • | или
    • \W - символ без слов.

отметим, что \W соответствует любым символам, кроме букв, цифр и _. Если вы хотите сопоставить слово, которое может появиться между _ (подчеркивает), вам нужен немного другой шаблон:

(^|[^[:alnum:]])test($|[^[:alnum:]])

на [^[:alnum:]] отрицаемое выражение скобки соответствует любому символу, кроме буквенно-цифровых символов, и спички _, так что _test_ будет соответствовать этому шаблону.

посмотреть это regex демо.