繁体   English   中英

如何在 Postgres 的字符串中搜索整个单词是否存在

[英]How to search if whole word exists in a String in Postgres

我有一个带有列field的表,该field值类似于三星手机。

我的问题是,如果我搜索字符串“Samsung”或“phone”,如何获得这一行。 如果我只给出“Sam”或“ph”作为搜索词,我不想要任何结果。

我曾尝试使用 ILIKE 运算符,但如果我使用:

select * 
from mytable 
where title ILIKE 'Samsung';

它不会给出任何结果,因为它认为标题应该完全相等。 此外,如果我使用title ILIKE '%Samsung%'那么它将适用于任何部分字符串。

简而言之,我想如果输入的搜索词作为一个完整的词存在于我的专栏中,那么只给出搜索结果。

另外,如果我有多个搜索词值,那么任何单词匹配都应该是结果

您可以为此使用正则表达式:

where title ~* '(\mphone\M)|(\msamsung\M)'

以上仅返回phonesamsung是完整单词的值。 正则表达式修饰符\\m\\M使模式只匹配整个单词。

正则表达式运算符~*使此不区分大小写。 上述表达式将返回Samsung PhoneGoogle Phone但不会返回Sam's House

如果要添加更多单词,只需使用“或”运算符添加它们即可|

where title ~* '(\mphone\M)|(\msamsung\M)|(\mbhat\M)'

请注意,这种搜索不会很快。 正则表达式很昂贵,它们不能使用任何索引。

你也可以使用这个:

title ~* '(^|[^\w])samsung([^\w]|$)'

上面一个的优点是,它可以很容易地扩展到包含来自不同编码的字符,如下所示:(土耳其字符)

title ~* '(^|[^\wğüşıöçĞÜŞİÖÇ])samsung([^\wğüşıöçĞÜŞİÖÇ]|$)

这是一个示例案例,您可能需要上述扩展。
例如; 在Latin5 编码的数据库中,您的值为'İsamsung'。 İ 在土耳其语中是 i 的首都。
在这种情况下, title ~* '(\\msamsung\\M)'不起作用。 此条件返回 İsamsung 值。 因为在 Latin5 编码中,postgre 认为 İ 超出了字母数字范围并且该值类似于 :samsung。

以下解决方案在 PostgreSQL 9.6 中进行了测试。

您可以使用\\y字边界和带有交替运算符的分组结构,以分隔所有可能的选择:

where title ~* '\y(?:Samsung|phone)\y'

或者,不区分大小写:

where title ~* '\y(?:Samsung|phone)\y'

请参阅PostgreSQL 演示

请注意,当第一个或最后一个字符不是单词字符时, \\y不是正确的方法。 例如,您想搜索#samsungphone# 然后,考虑使用明确的词边界

where title ~* '(?<!\w)(?:#samsung|phone#)(?!\w)'

在这里, (?<!\\w)负回顾后失败的比赛,如果有一个非alnum和无_立即字符到左侧的当前位置,和(?!\\w)是一个负向前查找失败的比赛如果在当前位置的右侧有一个 non-alnum 并且没有_ char。 等效于测试where子句中是否匹配:

where title ~* '(\W|^)(?:#samsung|phone#)(\W|$)'

在线查看另一个 PostgreSQL 演示

CREATE TABLE mmytable
    (title character varying)
;

INSERT INTO mmytable
    (title)
VALUES
    ('#Samsung Co.'),
    ('They have a phone#'),
    ('Uncle Sam phoned him')
;

select * from mmytable where title ~* '(?<!\w)(?:#samsung|phone#)(?!\w)';

在此处输入图片说明

此外,当您只需要在空白字符之间或字符串的开头/结尾进行匹配时,请考虑空白边界

where title ~* '(?<!\S)(?:#samsung|phone#)(?!\S)'
where title ~* '(\s|^)(?:#samsung|phone#)(\s|$)'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM