PostgreSQL 8.4 中的字符串匹配

String matching in PostgreSQL 8.4

我需要在 PostgreSQL 8.4 中实现正则表达式匹配(据我所知)。正则表达式匹配似乎只在 9.0+ 中可用。

我的需求是:

当我提供输入时 14.1 我需要得到这些结果:

14.1.1
14.1.2
14.1.Z
...

但不包括:

14.1.1.1
14.1.1.K
14.1.Z.3.A
...

模式不限于单个字符。总是有可能会出现这样的模式:14.1.1.2K14.1.Z.13.A2 等,因为该模式已提供给用户。应用程序无法控制模式(它不是版本号)。

知道如何在 Postgres 8.4 中实现它吗?

再问一问我的问题就解决了

你不能进行正则表达式匹配,但我相信你可以像运算符那样做:

SELECT * FROM table WHERE version LIKE '14.1._';

将匹配版本为“14.1”的任何行。后跟一个字符。这应该与您的示例相符。请注意,如果您也需要它,它不会只匹配“14.1”。您可以使用 OR 来做到这一点。

SELECT * FROM table WHERE version LIKE '14.1._' OR version = '14.1';

正则表达式匹配应该可以像这样在 Postgresql-8.4 中实现:

SELECT * FROM table WHERE version ~ '^14\.1\..$';

首先,regular expression matching has been in Postgres practically for ever, at least since version 7.1. Use the these operators

~ !~ ~* !~*

关于 dba.SE 的概述:

你的情况似乎是,不允许另一个点:

SELECT *
FROM   tbl
WHERE  version LIKE '14.1.%'        -- for performance
AND    version ~ '^14\.1\.[^.]+$';  -- for correct result

SQL Fiddle.

LIKE 表达式是多余的,但它会显着提高性能,即使没有索引。但是你当然应该有一个索引。

LIKE 表达式可以使用基本的 text_pattern_ops 索引,而正则表达式不能,至少在 Postgres 8.4 中是这样。

  • PostgreSQL LIKE query performance variations
正则表达式模式中的

[^.] 是排除点 (.) 的字符 class。所以任何其他字符都是允许的,只是没有更多的点。

性能

要获得此特定查询的最佳性能,您可以添加专门的索引:

CREATE INDEX tbl_specail_idx ON tbl
((length(version) - length(replace(version, '.', ''))), version text_pattern_ops);

并使用匹配查询,同上,只是将最后一行替换为:

AND   length(version) - length(replace(version, '.', '')) = 2

SQL Fiddle.