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 は true を返します。しかし、私がしようとすると:

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)'

それ以外の場合、式は問題なく、PostgreSQL9.1.4で機能します。WHERE句で使用するかSELECTリストで使用するかにかかわらず、古いバージョン(コメントで提案されている@kgrittnなど)でバグが発生している場合を除いて、違いはありません。


文字列リテラルの前にE。を付けると、表示されるエラーメッセージを引き起こす可能性があります。式はアイテムとして正常に機能すると述べたため、これでは問題を説明できません。SELECT

しかし、シャーロック・ホームズが引用しているように、「不可能を排除したとき、残っているものは何であれ、ありそうもないことは真実でなければならない」。

たぶん、1つのテストをで実行standard_conforming_strings = onし、もう1つのテストをで実行しましたstandard_conforming_strings = off-これは、9.1より前の古いバージョンでの文字列リテラルのデフォルトの解釈でした。たぶん2つの異なるクライアント(それに関して異なる設定を持っている)で。

詳細については、マニュアルの「Cスタイルのエスケープを使用した文字列定数」の章を参照してください。

于 2012-08-22T17:25:57.177 に答える