【问题标题】:Postgres regex issuePostgres正则表达式问题
【发布时间】:2012-08-22 09:02:40
【问题描述】:

我需要查找存储在 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}'

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

【问题讨论】:

  • 这是什么版本的PostgreSQL?最近对正则表达式处理进行了一些修复,因此次要版本号可能很重要。

标签: regex postgresql


【解决方案1】:

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

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

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

放在一起:

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

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


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

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

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

阅读手册中的String Constants with C-style Escapes一章了解更多信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-25
    • 1970-01-01
    相关资源
    最近更新 更多