Regex Postgres/TCL-flavor正则表达式:使用lookarounds否定匹配

Regex Postgres/TCL-flavor正则表达式:使用lookarounds否定匹配,regex,postgresql,regex-lookarounds,Regex,Postgresql,Regex Lookarounds,我有一个要匹配特定子字符串的查询。例如,让我们将所有条目与单词“rice”匹配: # 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

我有一个要匹配特定子字符串的查询。例如,让我们将所有条目与单词“rice”匹配:

# 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的条目

本质上,我想要一套(大米)-一套(1/2大米)。我在这里的攻击角度是使用一个将被否定的环视

# 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”的字符串。

请注意,
(?!r)ice
=
ice
as
i
不等于
r
(?!r)
是一种负前瞻,如果其模式与当前位置右侧的文本匹配,则匹配失败


你实际上想使用
”(?
(?!r)ice
=
ice
,因为
i
不等于
r
。你实际上想使用
”(?有趣的…我不知道“谢谢Wiktor!”这解决了我的问题。
CREATE TABLE tb1
    (s character varying)
;

INSERT INTO tb1
    (s)
VALUES
    ('Rice Veges'),
    ('1/2 Rice 1/2 Githeri')
;

SELECT * FROM tb1 WHERE s ~* '(?<!1/2 )rice';