web-dev-qa-db-ja.com

無効なメールアドレスを選択するために、Ruby regexをPostgres regexに変換します

私はインターネットのトロールとPostgresの正規表現のドキュメントのいくつかを読みましたが、私はここで質問をするのが最善の方法だと思う段階にあります。

私は次のRuby正規表現を持っています:

/\A[^@\s]+@([^@\s]+\.)+[^@\W]+\z/

Postgresの正規表現に変換しようとしています。これまでのところ私は思いつきました:

'\\A[^@\\s]\+@([^@\\s]+\\.)\+[^@\\W]\+\\z'

私はこれをオンラインのある記事で見つけたように:

したがって、+はPostgreSQLのメタ文字ですが、\+はプレーンな「プラス」文字です。

そしてこれは別のもので:

バックスラッシュは、PostgreSQL文字列の文字をエスケープするために使用されます。したがって、バックスラッシュを含む\wのような正規表現は、PostgreSQLステートメントでリテラル文字列として記述されると\\wになります。単一のリテラルバックスラッシュに一致させるには、PostgreSQLでは\\になる正規表現\\\\が必要です。

私が実行している合計クエリはこれです:

SELECT email
FROM users
WHERE email !~ '\\A[^@\\s]\+@([^@\\s]+\\.)\+[^@\\W]\+\\z'

そして、私はそれがゼロの結果を返すことを期待しています、それはそれがすべてのメールアドレスを選択しているように見えます。

演算子!~!~*も試した)を使用しているため、結果は期待できません。これは不一致を返すと考えられ、すべてのメールがデータベース内のアドレスがRuby regexをこの質問の上部に貼り付けた正規表現と一致します。これは、Rails app toデフォルトのメール検証設定を使用して、すべてのユーザーのメールを検証する)

したがって、Postgres用に正規表現の形式/構文を正しく変換していないという結論に達しましたが、他に何が欠けているのかわかりません。これが可能かどうか、可能であれば他に何を変更する必要があるかを教えてください。


その正規表現の翻訳に成功したら、2番目のRuby正規表現を作成します。これもPostgresに翻訳したいと思います。これは次のとおりです。

/\A[a-zA-Z0-9.!\#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\z/

これは、以下の仕様に従って有効なメールアドレスを持たないすべてのユーザーのメールを検索したいためです。 https://html.spec.whatwg.org/multipage/input.html#valid-メールアドレス

どうもありがとうございました????

2
samjewell

最初に生のテキストを選択するだけで正規表現をデバッグする必要があります。テキストレベルで希望どおりに認識されることを確認してください。

select '\\A[^@\\s]\+@([^@\\s]+\\.)\+[^@\\W]\+\\z';

                 ?column?                 
------------------------------------------   
\\A[^@\\s]\+@([^@\\s]+\\.)\+[^@\\W]\+\\z

したがって、二重にしたバックスラッシュは、おそらくあなたがそう思っていた方法で、単一に凝縮されませんでした。これは、standard_conforming_strings設定のデフォルト(オン)設定であることに注意してください。

したがって、正規表現パーサーは、バックスラッシュ付きのバックスラッシュを表示します。これは、リテラルバックスラッシュ文字に一致し、その後にリテラル 'A'が続き、リテラル 'A'に一致します。それは明らかにあなたが望むものではありません。

二重のバックスラッシュを削除できます。次に、使用するすべての表記がPostgreSQLでサポートされているかどうかを心配する必要があります。 \ Wは、角括弧内のPostgreSQLでは無効です なので、少なくとも1つはサポートされていません。

1
jjanes

ここに短い答えがあります:

'^[^@\s]+@([^@\s]+\.)+\w+$'

そして

$lbl$^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$$lbl$

2番目のものは ドル引用文字列定数 を使用して '

いくつかの例:

SELECT * 
   FROM (
      VALUES
         ('2'), 
         ('not_an_email'), 
         ('[email protected]'), 
         ('[email protected]'),
         ('[email protected]@om'),
         ('mail@[email protected]'),
         ('this\@example.com'),
         ($$th'[email protected]$$)
  ) t(email) 
 WHERE email ~ '^[^@\s]+@([^@\s]+\.)+\w+$';

収量

[email protected]
[email protected]
this\@example.com
th'[email protected]

そして

SELECT * 
   FROM (
      VALUES
         ('2'), 
         ('not_an_email'), 
         ('[email protected]'), 
         ('[email protected]'),
         ('[email protected]@om'),
         ('mail@[email protected]'),
         ('this\@example.com'),
         ($$th'[email protected]$$)
      ) t(email) 
   WHERE email ~ $some_label$^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$$$some_label$;

収量

[email protected]
[email protected]
th'[email protected]

これがあなたが探しているものであることを願っています

1
sinpamov