5

我需要找到存储在 postgres 中的所有记录,这些记录与以下正则表达式匹配:

^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}$

像这样的东西:

SELECT * FROM users WHERE users.phone ~ '^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}$'

但是这个错误:

无效的正则表达式:量词操作数无效

为什么 Postgres 不能使用这个正则表达式?

在普通的 Ruby 中使用相同的就可以了。

更新

问题只出在 WHERE 上。当我尝试:

SELECT '+79637434199' ~ '^((8|\+7)[\- ]?)(\(?\d{3}\)?[\- ]?)[\d\- ]{7,10}'

Postgres 返回真。但是当我尝试时:

SELECT * FROM users WHERE users.phone ~ '^((8|\+7)[\- ]?)(\(?\d{3}\)?[\- ]?)[\d\- ]{7,10}'

结果:“无效的正则表达式:量词操作数无效”

4

1 回答 1

5

当你把它放在第一个或最后一个位置时,你不需要-在字符类中转义,因为它不会被误读为范围:

[\- ]-> [- ]
[\d\- ]->[\d -]

最终获得上限的方式10是徒劳的。在末尾
添加以禁止尾随字符。 或禁止尾随数字(但需要非数字)。 或者在那里结束字符串或有一个非数字跟随。$
\D
($|\D)

放在一起:

SELECT '+79637434199' ~ '^(8|\+7)[ -]?(\(?\d{3}\)?[ -]?)[\d -]{7,10}($|\D)'

否则你的表达就好了,它适用于我在 PostgreSQL 9.1.4 上。WHERE无论您在子句中还是在列表中使用它都不应该有任何区别SELECT- 除非您遇到一些旧版本的错误(如评论中建议的@kgrittn)。


如果我在字符串文字前加上E,我可以引发您收到的错误消息。这无法解释您的问题,因为您声明该表达式作为SELECT项目工作正常。

但是,正如夏洛克·福尔摩斯所引述的那样,“当你排除了不可能的事情时,剩下的任何事情,无论多么不可能,都必须是真相。”

也许您运行了一个测试,standard_conforming_strings = on另一个运行了standard_conforming_strings = off- 这是 9.1 之前的旧版本中字符串文字的默认解释。也许有两个不同的客户(对此有不同的设置)。

在手册中使用 C 样式转义符的字符串常量一章中阅读更多信息。

于 2012-08-22T17:25:57.177 回答