在 PostgreSQL 中选择字符串是否包含子串匹配

Bilal Shahid 2023年1月30日 2022年5月14日
  1. 在 PostgreSQL 中如果字符串包含子字符串匹配,则使用 like 运算符 SELECT
  2. 在 PostgreSQL 中如果字符串包含子字符串匹配,则使用 position() 函数 SELECT
  3. 在 PostgreSQL 中如果字符串包含子字符串匹配,则使用 similar to 正则表达式来 SELECT
  4. 在 PostgreSQL 中如果字符串包含子字符串匹配,则使用 substring() 函数 SELECT
  5. 在 PostgreSQL 中如果字符串包含子字符串匹配,则使用 Posix 正则运算符来 SELECT
在 PostgreSQL 中选择字符串是否包含子串匹配

今天,我们将学习如何在 PostgreSQL 字符串中查找一个值,并在它匹配特定条件时选择它。

假设你有一个字符串 carabc,并想查看它是否包含值 car。因此,你将尝试使用一个函数来告诉你字符串中是否存在这样的子字符串。

PostgreSQL 提供了三种方法:likesimilar toPosix 运算符。我们将详细讨论这些。

在 PostgreSQL 中如果字符串包含子字符串匹配,则使用 like 运算符 SELECT

如果字符串包含特定的子字符串,like 表达式将返回 True;否则,错误。首先,我们创建一个表并在其中插入一些值:

create table strings(
    str TEXT PRIMARY KEY
);

insert into strings values ('abcd'), ('abgh'), ('carabc');

现在,让我们从该表中选择 abc 值。

select * from strings where str like 'abc';

当我们运行它时,什么也没有发生。显示一个空表。

为什么它没有从表中返回 abcdcarabc?看看下面的语句并尝试看看会发生什么:

select * from strings where str like 'abcd';

输出:

使用 Like 运算符查找字符串匹配

因此,现在你看到调用 like 往往会返回与我们尝试匹配的字符串完全相同的结果。

要将其与子字符串匹配,你需要在尝试匹配的子字符串中添加一个%

以下提供了一个更好的示例来说明如何做到这一点:

select * from strings where str like '%abc%';

输出:

使用 Like 运算符和 % 来查找字符串匹配

%x 告诉查询我们需要在字符串中的一些其他值位于此 x 后面之后找到 x。如果我们想找到 carabc,我们会说%abc,它会返回 carabc,因为 car 附加在 abc 之前。

但是如果我们想返回 abcd,我们将使用 x%,因为 d 附加在 x 之后。自己尝试一下,看看结果以获得更好的理解!

因为我们想检查一个字符串是否包含可能位于左侧、右侧或中间的 abc,所以我们使用%abc%返回所有此类字符串。

like 运算符也可以写为~~,如果 not like,则使用!~~

另一个表达式被称为 Ilike 有助于匹配字符串而不区分大小写。这意味着如果我们使用以下语句:

select * from strings where str Ilike '%Abc%';

即使 abc 不等于 Abc,它也会返回先前的结果,因为 a 在子字符串中大写。

like 运算符一样,你可以将 Ilike 写为~~*,将 not Ilike 写为!~~*

假设你要运行查询来检查表中与特定字符串匹配的记录。如果要将 abcde 与表中的记录进行比较并返回匹配的行,可以使用:

select * from strings where 'abcd' like '%' || str || '%'

这会将 str 列中的行附加到 %_str_% 的语法中,然后我们可以比较其中的每个值并查看哪些匹配。

输出:

使用 Like 运算符比较字符串并返回行

要将子字符串与诸如 escape%或反斜杠/、\之类的流氓字符匹配,你可以使用,

select * from strings where 'abcd' like '%/abc'

这将不返回任何内容,因为函数无法消除值%。这将我们带到下一点,使用 position 函数。

在 PostgreSQL 中如果字符串包含子字符串匹配,则使用 position() 函数 SELECT

position() 函数是检查字符串中是否存在子字符串的更好选择。这是在 PostgreSQL 文档中的字符串操作下定义的。

它返回在主字符串中找到的子字符串的索引。因此,如果我们要在 carabc 中找到 car,它将返回 1。

这样,我们可以通过检查返回索引的值来查看字符串中是否存在任何子字符串。如果大于 0,则子串存在;否则,它不会。

select * from strings where position(str in 'abcde') > 0

上面的语句将返回两个值,aabcd,因为它们都存在于 abcde 中。你可以根据需要进行操作。

此外,如果你的子字符串中有任何其他字符,例如 %,它会在检查中跳过该字符并返回准确的结果,使其比 like 表达式好得多。

select * from strings where position(str in '% abcde') > 0

运行上述将给出相同的结果。

position 表达式的可能替代品可以是 strpos,它同样有效。

在 PostgreSQL 中如果字符串包含子字符串匹配,则使用 similar to 正则表达式来 SELECT

likesimilar to 之间的唯一区别是后者是在各种其他 DMBS 中使用的标准 SQL 定义。

select * from strings where position(str in 'abcde') > 0

这将返回与 like 表达式相同的结果。

要使用替代匹配,你可以使用:

select * from strings where str similar to '%(abc|a)%'

这将返回匹配 abca 的所有字符串。当我们运行这个查询时,我们会返回表中的所有字符串,因为每个字符串都包含一个 a

如果你想禁用匹配子字符串中的任何元字符,你可以使用反斜杠 \ 来禁用我们倾向于在字符串中称为流氓字符的内容。

在 PostgreSQL 中如果字符串包含子字符串匹配,则使用 substring() 函数 SELECT

可以对 substring() 函数进行另一种操作,如下所示:

select * from strings where str ~~ substring(str similar '%abc%' escape '#')

substring() 在我们的例子中返回类似于 abc 或包含 abc 的字符串。然后,我们使用 ~~ 运算符(like 的缩写)将返回的结果与 str 匹配,如果匹配,我们从表中选择结果。

这个简单的函数甚至有助于将字符串分成单独的部分,可以在提供的语法中看到:

substring(string similar pattern escape escape-character)

or

substring(string from a pattern for escape-character)

or

substring(string, pattern, escape-character)

escape-character 倾向于将要匹配的字符串分成不同的部分,如果它在不同点包含 escape-character

因此,如果我们运行该语句:

select * from strings where str ~~ substring(str similar '#"abcd#"%' escape '#')

'#"abcd#"%' 将被分成 abcd,用两个 # 字符括起来。因此,我们也可以找到匹配的字符串 abcd

在 PostgreSQL 中如果字符串包含子字符串匹配,则使用 Posix 正则运算符来 SELECT

正则表达式

以上内容取自 PostgreSQL 文档中描述的执行相同匹配功能的 Posix 运算符的表。

你可以使用如下语句来查看字符串是否包含子字符串:

select * from strings where str ~ 'abc'

这将返回值 carabcabcd

你甚至可以使用 regexp_match(string, pattern [, flags]),如果没有找到匹配项,则返回 null。如果找到匹配项,它将返回一个数组,其中包含与模式匹配的所有子字符串。

要理解这一点,请查看以下查询:

select regexp_match('abdfabc', 'abd')

输出:

使用 regexp_match 查找匹配 1

使用另一个查询,

select regexp_match('abdfabc', 'abf')

输出:

使用 regexp_match 查找匹配 2

现在,你将看到这个表达式如何找到一个模式并返回它。你可以在函数中使用此表达式,调用该函数进行 select 操作,然后返回所有匹配的字符串。

Author: Bilal Shahid
Bilal Shahid avatar Bilal Shahid avatar

Hello, I am Bilal, a research enthusiast who tends to break and make code from scratch. I dwell deep into the latest issues faced by the developer community and provide answers and different solutions. Apart from that, I am just another normal developer with a laptop, a mug of coffee, some biscuits and a thick spectacle!

GitHub