17

RFC5321 / RFC5322に従って電子メールアドレスを検証する正規表現を知っている人はいますか?

(ネスト可能な)コメントは文法を不規則にするので、コメントのないアドレスのみが考慮されるべきです。

もちろん、実際に誰かが所有しているアドレスの検証に関心がある場合、実際の検証は、そのアドレスに電子メールを送信し、所有者がそれを受け取ったかどうかを確認することだけです。しかし、私はRFC標準に純粋に興味があります。実用的なアプローチの場合、この質問はより適切です。

コメントに加えて、折り畳み空白を犠牲にするつもりですが、それを除けば、RFC5321/2で有効なアドレスを拒否する式には興味がありません。(おそらく、折り畳みの空白を無視することは、状況によっては意味があります。)

理想的には、正規表現はRFCで有効ではないものをすべて拒否しますが、それはそれほど重要ではありません。たとえば、正規表現にトップレベルドメインの網羅的なリストを含めることはそれほど興味深いことではありません。トップレベルドメインを受け入れるだけで十分です。

アドレスタグ(例:address + tag@domain.org)が私が言及したRFCの一部であるかどうかはわかりませんが、正規表現でこれらを検証してほしいと思います。

IPv6は間違いなく正しく処理される必要があります(RFC5952)。

私が理解しているように、国際化された電子メール(RFC6530RFC6531RFC6532RFC6533)はまだ実験段階ですが、これらのアドレスを検証する式も興味深いでしょう。

答えを普遍的に面白くするために、正規表現がPOSIX形式であるとよいでしょう。

4

2 に答える 2

23

必要なコメントにより、電子メールアドレスの文法が不規則になります(文脈自由)。ただし、コメントを除外すると、結果の文法は正規文法になります。一次定義では、字句トークン間の空白を(折りたたむ)ことができます(例a @ b.com)。折りたたまれている空白をすべて削除すると、標準形になります。

これは、RFC 5322(コメントを除く)に準拠した正規の電子メールアドレスの正規表現です。

([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|\[[\t -Z^-~]*])

折りたたみ空白を受け入れる必要がある場合、これはRFC 5322(コメントを除く)に準拠した電子メールアドレスの正規表現です。

((([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?"(((([\t ]*\r\n)?[\t ]+)?([]!#-[^-~]|(\\[\t -~])))+(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?)"(([\t ]*\r\n)?[\t ]+)?)@((([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?\[((([\t ]*\r\n)?[\t ]+)?[!-Z^-~])*(([\t ]*\r\n)?[\t ]+)?](([\t ]*\r\n)?[\t ]+)?)

有効な電子メールアドレスは、RFC 5321(SMTP)でさらに制限されています。基本的には@記号の前の部分だけを残しますが、@記号の後のホスト名またはアドレスリテラルのみを受け入れます。("---.---"は有効なドットアトムですが、有効なホスト名ではありません。 "[...]"は有効なドメインリテラルですが、有効なアドレスリテラルではありません。)

RFC 5321に示されている文法は、ホスト名とIPアドレスの両方に関しては寛大すぎます。私は、このドラフトRFC 1034(セクション3.5)をガイドラインとして使用して、問題のルールを「修正」する自由を取りました。結果の正規表現は次のとおりです。

([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)*|\[((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+)])

すべての正規表現はPOSIXEREです。最後のものはネガティブ先読みを使用します。正規表現の派生については、ここを参照してください。

于 2014-11-18T08:08:44.713 に答える
-2

アップデート:

Michael StramelがRFC822が古くなっていると指摘したので、彼のコメントを参照してください。


私の知る限り、RFC822は電子メールアドレスの構文を指定しています。

http://www.ex-parrot.com/pdw/Mail-RFC822-Address.html

于 2012-12-21T15:27:50.650 に答える