У меня есть запрос, в котором я хотел бы сопоставить определенную подстроку. В качестве примера, давайте сопоставим все записи со словом «рис»:
# select name from menus where name ~* 'rice' order by price limit 3;
name
----------------------
Rice Veges
1/2 Rice 1/2 Githeri
1/2 Rice 1/2 Chapo
(3 rows)
Более конкретное совпадение также работает. Обратите внимание на добавление 1/2
select name from menus where name ~* '(1/2) rice' order by price limit 3;
name
----------------------
1/2 Rice 1/2 Githeri
1/2 Rice 1/2 Chapo
1/2 Rice 1/2 Matoke
(3 rows)
Итак, допустим, я хочу выбрать весь рис, но я не хочу записей с 1/2 в нем.
По сути, я хочу Set (Rice) - Set (1/2 Rice). Мой угол атаки здесь - использовать взгляд, который будет отрицаться.
# select name from menus where name ~* '(?!1/2) rice' order by price limit 3;
name
----------------------
1/2 Rice 1/2 Chapo
1/2 Rice 1/2 Githeri
1/2 Rice 1/2 Matoke
Как видите, вышеприведенное выражение не работает, так как оно все еще соответствует подстроке 1/2
# select name from menus where name ~* '(?!2)\s*rice' order by price limit 3;
name
----------------------
Rice Veges
1/2 Rice 1/2 Githeri
1/2 Rice 1/2 Chapo
Упрощение выражения для удаления '1 /', которое может вызывать проблемы из-за неправильно экранированных строк, не дает того, что мы хотим.
Мы можем подтвердить, что поддерживаются отрицательные сведения:
# select name from menus where name ~* '(?!r)ice' order by price limit 3;
name
-----------------
Juice Container
Mango Juice
Passion Juice
Это соответствует любой строке, которая имеет «ice», но перед ней не стоит «r».