2012-08-22 107 views
4

我需要找到存儲在Postgres的所有記錄,下面的正則表達式,其匹配:Postgres的正則表達式的問題

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

事情是這樣的:

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

但隨着錯誤此此起彼伏:

invalid regular expression: quantifier operand invalid

爲什麼Postgres不能使用這個正則表達式?

在普通Ruby中使用相同的工作方式很好。

UPDATE

問題是隻與WHERE。當我嘗試:

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

Postgres返回true。但是,當我嘗試:

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

結果:「無效的正則表達式:量詞操作無效」

+2

什麼版本的PostgreSQL是什麼?已經有正則表達式中的一些修復最近處理,所以次要版本號可能是顯著。 – kgrittn

回答

4

您不需要時將其放在第一個或最後一個位置,以逃避-內部字符類,因爲它不能被誤讀爲範圍的方式:

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

最終上限10的方式是徒勞的。
在末尾添加$以禁止拖尾字符。
\D不允許結尾數字(但需要非數字)。
($|\D)可以在那裏結束字符串或者具有非數字後續。

放在一起:

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

否則你的表情就好了,它爲我的作品上的PostgreSQL 9.1.4。不管你在WHERE子句中還是在SELECT列表中使用它,都不應該有任何區別 - 除非你遇到了一些舊版本(如評論中建議的@kgrittn)的bug。


如果我在前面加上字符串字面量E,我能挑起你得到的錯誤消息。這不能解釋你的問題,因爲你聲明表達作品正常SELECT項目。但是,正如福爾摩斯所引用的那樣,「當你排除了不可能的事物時,無論如何,不​​管可能性如何,都必須是事實。有兩個不同的客戶端(即具有不同的設置爲這一點),這是字符串字面量在舊版本的缺省解釋9.1之前也許

- 「

也許你運行一個測試用standard_conforming_strings = on,另一個與standard_conforming_strings = off

更多的章節String Constants with C-style Escapes在手冊中。