正規表現を使用してメールアドレスを検証するにはどうすればよいですか?

3429
acrosman 2008-10-15 04:14.

何年にもわたって、サーバー部分としてIPアドレスを使用しないことを前提として、MOST電子メールアドレスを正しく検証する正規表現をゆっくりと開発してきました。

私はそれをいくつかのPHPプログラムで使用しており、ほとんどの場合機能します。しかし、それを使用しているサイトで問題を抱えている人から連絡があり、調整が必要になることがあります(最近、4文字のTLDを許可していないことに気付きました)。

電子メールを検証するためにあなたが持っている、または見た中で最高の正規表現は何ですか?

いくつかの短い式を使用する関数を使用するソリューションをいくつか見てきましたが、より複雑な関数でいくつかの短い式を使用するのではなく、単純な関数で1つの長い複雑な式を使用したいと思います。

30 answers

2561
bortzmeyer 2008-10-15 04:26.

完全にRFC 822に準拠した正規表現は、その長さの非効率的かつ曖昧です。幸い、RFC 822は2回置き換えられ、電子メールアドレスの現在の仕様はRFC5322です。RFC 5322は、数分間学習すれば理解でき、実際の使用に十分効率的な正規表現につながります。

1つのRFC5322準拠の正規表現は、ページの上部にあります。 http://emailregex.com/ただし、インターネット上に浮かんでいるIPアドレスパターンを使用して00おり、ドット区切りのアドレスで符号なしバイトの10進値を許可するバグがあります。これは違法です。残りの部分はRFC5322文法と一致しているようで、grep -Poドメイン名、IPアドレス、不正なもの、引用符付きと引用符なしのアカウント名など、を使用していくつかのテストに合格しています。

00IPパターンのバグを修正すると、機能するかなり高速な正規表現が得られます。(実際のコードでは、マークダウンではなく、レンダリングされたバージョンをスクレイプします。)

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%& '* + / =?^ _ `{|} 〜-] +)* |"(?:[\ x01- \ x08 \ x0b \ x0c \ x0e- \ x1f \ x21 \ x23- \ x5b \ x5d- \ x7f] | \\ [\ x01- \ x09 \ x0b \ x0c \ x0e- \ x7f])* ")@(?:(?:[a-z0-9](?:[a-z0-9- ] * [a-z0-9])?\。)+ [a-z0-9](?:[a-z0-9-] * [a-z0-9])?| \ [(?:( ?:( 2(5 [0-5] | [0-4] [0-9])| 1 [0-9] [0-9] | [1-9]?[0-9]))\ 。){3}(?:( 2(5 [0-5] | [0-4] [0-9])| 1 [0-9] [0-9] | [1-9]?[0 -9])| [a-z0-9-] * [a-z0-9]:(?:[\ x01- \ x08 \ x0b \ x0c \ x0e- \ x1f \ x21- \ x5a \ x53- \ x7f ] | \\ [\ x01- \ x09 \ x0b \ x0c \ x0e- \ x7f])+)\])

または:

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

ここで図の有限状態機械正規表現自体より明らかである上記の正規表現のためには

PerlおよびPCREのより洗練されたパターン(PHPなどで使用される正規表現ライブラリ)は、問題なくRFC5322を正しく解析できます。PythonとC#でもそれを行うことができますが、最初の2つとは異なる構文を使用します。ただし、あまり強力ではないパターンマッチング言語のいずれかを使用せざるを得ない場合は、実際のパーサーを使用するのが最善です。

RFCに従って検証しても、そのアドレスが指定されたドメインに実際に存在するかどうか、またはアドレスを入力する人がその真の所有者であるかどうかについてはまったく何もわからないことを理解することも重要です。人々はいつもこの方法で他の人をメーリングリストに登録します。そのアドレスを、そのアドレスと同じWebページに入力することを意図した確認トークンを含むメッセージを送信することを含む、より洗練された種類の検証を必要とする修正。

確認トークンは、入力者の住所を取得したことを知る唯一の方法です。これが、ほとんどのメーリングリストが現在そのメカニズムを使用してサインアップを確認している理由です。結局のところ、誰でも下[email protected]に置くことができ、それは合法であるとさえ解析されますが、それは反対側の人である可能性は低いです。

PHPの場合、「PHPを使用した電子メールアドレスの検証」で指定されているパターンを使用しないでください。これは、私が引用する正しい方法です。

一般的な使用法と広範囲にわたるずさんなコーディングにより、記録された正式な標準よりも制限の厳しい電子メールアドレスの事実上の標準が確立される危険性があります。

これは、他のすべての非RFCパターンよりも優れているわけではありません。RFC 5322は言うまでもなく、RFC 822さえも処理できるほど賢くはありません。しかし、これはそうです。

派手で衒学的になりたい場合は、完全な状態エンジンを実装してください。正規表現は、基本的なフィルターとしてのみ機能します。正規表現の問題は、正規表現では処理できないため、完全に有効な電子メールアドレスが無効(誤検知)であることを誰かに伝えることは、ユーザーの観点からは失礼で失礼なことです。この目的の状態エンジンは、各RFCに従って電子メールアドレスを分解するため、無効と見なされる電子メールアドレスを検証し、修正することもできます。これにより、次のような、より快適なエクスペリエンスが可能になります。

指定されたメールアドレス「myemail @ address、com」は無効です。'[email protected]'のことですか?

コメントを含む、電子メールアドレスの検証も参照してください。または正規表現を検証する電子メールアドレスの比較。

Debuggexデモ

769
SLaks 2009-12-15 10:43.

電子メールアドレスの検証に正規表現を使用しないでください。

代わりに、次のようにMailAddressクラスを使用します。

try {
    address = new MailAddress(address).Address;
} catch(FormatException) {
    // address is invalid
}

このMailAddressクラスは、BNFパーサーを使用して、RFC822に完全に準拠してアドレスを検証します。

を使用しMailAddressて電子メールアドレスを検証する場合は、このアプローチでは電子メールアドレスの表示名の部分も受け入れられるため、これが目的の方法とは異なる場合があることに注意してください。たとえば、次の文字列を有効な電子メールアドレスとして受け入れます。

これらの場合のいくつかでは、文字列の最後の部分だけがアドレスとして解析されます。その前の残りは表示名です。表示名のないプレーンな電子メールアドレスを取得するには、正規化されたアドレスを元の文字列と照合します。

bool isValid = false;

try
{
    MailAddress address = new MailAddress(emailAddress);
    isValid = (address.Address == emailAddress);
    // or
    // isValid = string.IsNullOrEmpty(address.DisplayName);
}
catch (FormatException)
{
    // address is invalid
}

さらに、のように末尾にドット[email protected]が付いているアドレスもMailAddressで受け入れられます。

本当に正規表現を使用したい場合は、ここにあります:

(?:(?:\ r \ n)?[\ t])*(?:(?:(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031 ] +(?:(?:(?:\ r \ n)?[\ t]
)+ | \ Z |(?= [\ ["()<> @、;:\\"。\ [​​\]]))| "(?:[^ \" \ r \\] | \\。 |(?:(?:\ r \ n)?[\ t]))* "(?:(?:
\ r \ n)?[\ t])*)(?:\。(?:(?:\ r \ n)?[\ t])*(?:[^()<> @、;:\ \ "。\ [​​\] \ 000- \ 031] +(?:(?:(
?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、;:\\"。\ [​​\]]))| "(?:[ ^ \ "\ r \\] | \\。|(?:(?:\ r \ n)?[ 
\ t]))* "(?:(?:\ r \ n)?[\ t])*))* @(?:(?:\ r \ n)?[\ t])*(?: [^()<> @、;:\\ "。\ [​​\] \ 000- \ 0
31] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、;:\\"。\ [​​\ ]]))| \ [([^ \ [\] \ r \\] | \\。)* \
](?:(?:\ r \ n)?[\ t])*)(?:\。(?:(?:\ r \ n)?[\ t])*(?:[^() <> @、;:\\ "。\ [​​\] \ 000- \ 031] +
(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、;:\\"。\ [​​\]]) )| \ [([^ \ [\] \ r \\] | \\。)* \](?:
(?:\ r \ n)?[\ t])*))* |(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?: (?:(?:\ r \ n)?[\ t])+ | \ Z
|(?= [\ ["()<> @、;:\\"。\ [​​\]]))| "(?:[^ \" \ r \\] | \\。|(?:( ?:\ r \ n)?[\ t]))* "(?:(?:\ r \ n)
?[\ t])*)* \ <(?:(?:\ r \ n)?[\ t])*(?:@(?:[^()<> @、;:\\ "。 \ [\] \ 000- \ 031] +(?:(?:(?:\
r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、;:\\"。\ [​​\]]))| \ [([^ \ [\ ] \ r \\] | \\。)* \](?:(?:\ r \ n)?[
 \ t])*)(?:\。(?:(?:\ r \ n)?[\ t])*(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)
?[\ t])+ | \ Z |(?= [\ ["()<> @、;:\\"。\ [​​\]]))| \ [([^ \ [\] \ r \ \] | \\。)* \](?:(?:\ r \ n)?[\ t]
)*))*(?:、@(?:(?:\ r \ n)?[\ t])*(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[
 \ t])+ | \ Z |(?= [\ ["()<> @、;:\\"。\ [​​\]]))| \ [([^ \ [\] \ r \\] | \\。)* \](?:(?:\ r \ n)?[\ t])*
)(?:\。(?:(?:\ r \ n)?[\ t])*(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031 ] +(?:(?:(?:\ r \ n)?[\ t]
)+ | \ Z |(?= [\ ["()<> @、;:\\"。\ [​​\]]))| \ [([^ \ [\] \ r \\] | \\ 。)* \](?:(?:\ r \ n)?[\ t])*))*)
*:(?:(?:\ r \ n)?[\ t])*)?(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] + (?:(?:(?:\ r \ n)?[\ t])+
| \ Z |(?= [\ ["()<> @、;:\\"。\ [​​\]]))| "(?:[^ \" \ r \\] | \\。|( ?:(?:\ r \ n)?[\ t]))* "(?:(?:\ r
\ n)?[\ t])*)(?:\。(?:(?:\ r \ n)?[\ t])*(?:[^()<> @、;:\\ " 。\ [\] \ 000- \ 031] +(?:(?:( ?:
\ r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、;:\\"。\ [​​\]]))| "(?:[^ \ "\ r \\] | \\。|(?:(?:\ r \ n)?[\ t
]))* "(?:(?:\ r \ n)?[\ t])*))* @(?:(?:\ r \ n)?[\ t])*(?:[^ ()<> @、;:\\ "。\ [​​\] \ 000- \ 031
] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、;:\\"。\ [​​\] ]))| \ [([^ \ [\] \ r \\] | \\。)* \](
?:(?:\ r \ n)?[\ t])*)(?:\。(?:(?:\ r \ n)?[\ t])*(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?
:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、;:\\"。\ [​​\]]))| \ [([^ \ [\] \ r \\] | \\。)* \](?:(?
:\ r \ n)?[\ t])*))* \>(?:(?:\ r \ n)?[\ t])*)|(?:[^()<> @、; :\\ "。\ [​​\] \ 000- \ 031] +(?:(?
:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、;:\\"。\ [​​\]]))| "(? :[^ \ "\ r \\] | \\。|(?:(?:\ r \ n)?
[\ t]))* "(?:(?:\ r \ n)?[\ t])*)*:(?:(?:\ r \ n)?[\ t])*(?: (?:(?:[^()<> @、;:\\ "。\ [​​\] 
\ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、;:\\" 。\ [\]]))| "(?:[^ \" \ r \\] |
\\。|(?:(?:\ r \ n)?[\ t]))* "(?:(?:\ r \ n)?[\ t])*)(?:\。(? :(?:\ r \ n)?[\ t])*(?:[^()<>

@、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ [ "()<> @、;:\\"。\ [​​\]]))| "
(?:[^ \ "\ r \\] | \\。|(?:(?:\ r \ n)?[\ t]))*"(?:(?:\ r \ n)?[ \ t])*))* @(?:(?:\ r \ n)?[\ t]
)*(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t]) + | \ Z |(?= [\ ["()<> @、;:\\
"。\ [​​\]]))| \ [([^ \ [\] \ r \\] | \\。)* \](?:(?:\ r \ n)?[\ t])* )(?:\。(?:(?:\ r \ n)?[\ t])*(?
:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、;:\\"。\ [
\]]))| \ [([^ \ [\] \ r \\] | \\。)* \](?:(?:\ r \ n)?[\ t])*))* | (?:[^()<> @、;:\\ "。\ [​​\] \ 000-
\ 031] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、;:\\"。\ [ \]]))| "(?:[^ \" \ r \\] | \\。|(
?:(?:\ r \ n)?[\ t]))* "(?:(?:\ r \ n)?[\ t])*)* \ <(?:(?:\ r \ n)?[\ t])*(?:@(?:[^()<> @、;
:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["() <> @、;:\\ "。\ [​​\]]))| \ [([
^ \ [\] \ r \\] | \\。)* \](?:(?:\ r \ n)?[\ t])*)(?:\。(?:(?:\ r \ n)?[\ t])*(?:[^()<> @、;:\\ "
。\ [\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、 ;:\\ "。\ [​​\]]))| \ [([^ \ [\
] \ r \\] | \\。)* \](?:(?:\ r \ n)?[\ t])*))*(?:、@(?:(?:\ r \ n )?[\ t])*(?:[^()<> @、;:\\ "。\
[\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、;: \\ "。\ [​​\]]))| \ [([^ \ [\] \
r \\] | \\。)* \](?:(?:\ r \ n)?[\ t])*)(?:\。(?:(?:\ r \ n)?[\ t])*(?:[^()<> @、;:\\ "。\ [​​\] 
\ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、;:\\" 。\ [\]]))| \ [([^ \ [\] \ r \\]
| \\。)* \](?:(?:\ r \ n)?[\ t])*))*)*:(?:(?:\ r \ n)?[\ t])* )?(?:[^()<> @、;:\\ "。\ [​​\] \ 0
00- \ 031] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、;:\\"。 \ [\]]))| "(?:[^ \" \ r \\] | \\
。|(?:(?:\ r \ n)?[\ t]))* "(?:(?:\ r \ n)?[\ t])*)(?:\。(?:( ?:\ r \ n)?[\ t])*(?:[^()<> @、
;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["( )<> @、;:\\ "。\ [​​\]]))|"(?
:[^ \ "\ r \\] | \\。|(?:(?:\ r \ n)?[\ t]))*"(?:(?:\ r \ n)?[\ t ])*))* @(?:(?:\ r \ n)?[\ t])*
(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、;:\\"。
\ [\]]))| \ [([^ \ [\] \ r \\] | \\。)* \](?:(?:\ r \ n)?[\ t])*)( ?:\。(?:(?:\ r \ n)?[\ t])*(?:[
^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |( ?= [\ ["()<> @、;:\\"。\ [​​\]
]))| \ [([^ \ [\] \ r \\] | \\。)* \](?:(?:\ r \ n)?[\ t])*))* \>( ?:(?:\ r \ n)?[\ t])*)(?:、\ s *(
?:(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t]) + | \ Z |(?= [\ ["()<> @、;:\\
"。\ [​​\]]))|"(?:[^ \ "\ r \\] | \\。|(?:(?:\ r \ n)?[\ t]))*"(? :(?:\ r \ n)?[\ t])*)(?:\。(?:(
?:\ r \ n)?[\ t])*(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(? :\ r \ n)?[\ t])+ | \ Z |(?= [
\ ["()<> @、;:\\"。\ [​​\]]))| "(?:[^ \" \ r \\] | \\。|(?:(?:\ r \ n)?[\ t]))* "(?:(?:\ r \ n)?[\ t
])*))* @(?:(?:\ r \ n)?[\ t])*(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t
])+ | \ Z |(?= [\ ["()<> @、;:\\"。\ [​​\]]))| \ [([^ \ [\] \ r \\] | \ \。)* \](?:(?:\ r \ n)?[\ t])*)(?
:\。(?:(?:\ r \ n)?[\ t])*(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +( ?:(?:(?:\ r \ n)?[\ t])+ |
\ Z |(?= [\ ["()<> @、;:\\"。\ [​​\]]))| \ [([^ \ [\] \ r \\] | \\。)* \](?:(?:\ r \ n)?[\ t])*))* |(?:
[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z | (?= [\ ["()<> @、;:\\"。\ [​​\
]]))| "(?:[^ \" \ r \\] | \\。|(?:(?:\ r \ n)?[\ t]))* "(?:(?:\ r \ n)?[\ t])*)* \ <(?:(?:\ r \ n)
?[\ t])*(?:@(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["
()<> @、;:\\ "。\ [​​\]]))| \ [([^ \ [\] \ r \\] | \\。)* \](?:(?:\ r \ n)?[\ t])*)(?:\。(?:(?:\ r \ n)
?[\ t])*(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)? [\ t])+ | \ Z |(?= [\ ["()<>

@、;:\\ "。\ [​​\]]))| \ [([^ \ [\] \ r \\] | \\。)* \](?:(?:\ r \ n)? [\ t])*))*(?:、@(?:(?:\ r \ n)?[
 \ t])*(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、
;:\\ "。\ [​​\]]))| \ [([^ \ [\] \ r \\] | \\。)* \](?:(?:\ r \ n)?[\ t])*)(?:\。(?:(?:\ r \ n)?[\ t]
)*(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t]) + | \ Z |(?= [\ ["()<> @、;:\\
"。\ [​​\]]))| \ [([^ \ [\] \ r \\] | \\。)* \](?:(?:\ r \ n)?[\ t])* ))*)*:(?:(?:\ r \ n)?[\ t])*)?
(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ ["()<> @、;:\\"。
\ [\]]))| "(?:[^ \" \ r \\] | \\。|(?:(?:\ r \ n)?[\ t]))* "(?:( ?:\ r \ n)?[\ t])*)(?:\。(?:(?:
\ r \ n)?[\ t])*(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t])+ | \ Z |(?= [\ [
"()<> @、;:\\"。\ [​​\]]))| "(?:[^ \" \ r \\] | \\。|(?:(?:\ r \ n) ?[\ t]))* "(?:(?:\ r \ n)?[\ t])
*))* @(?:(?:\ r \ n)?[\ t])*(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?:(?:(?:\ r \ n)?[\ t])
+ | \ Z |(?= [\ ["()<> @、;:\\"。\ [​​\]]))| \ [([^ \ [\] \ r \\] | \\。 )* \](?:(?:\ r \ n)?[\ t])*)(?:\
。(?:(?:\ r \ n)?[\ t])*(?:[^()<> @、;:\\ "。\ [​​\] \ 000- \ 031] +(?: (?:(?:\ r \ n)?[\ t])+ | \ Z
|(?= [\ ["()<> @、;:\\"。\ [​​\]]))| \ [([^ \ [\] \ r \\] | \\。)* \] (?:(?:\ r \ n)?[\ t])*))* \>(?:(
?:\ r \ n)?[\ t])*))*)?; \ s *)
548
JacquesB 2008-10-15 09:40.

この質問はよく聞かれますが、なぜ構文的に電子メールアドレスを検証したいのを自問する必要があると思います。本当にメリットは何ですか?

  • 一般的なタイプミスは検出されません。
  • 無効なメールアドレスや偽造されたメールアドレスを入力したり、他人のアドレスを入力したりすることを妨げるものではありません。

メールが正しいことを確認したい場合は、確認メールを送信してユーザーに返信してもらう以外に方法はありません。多くの場合、あなたがします持っているセキュリティ上の理由や倫理的な理由のために、とにかく確認メールを送信するために(そうすることができます彼らの意思に反してサービスまでありません例えばサイン誰かが)。

389
Andy Lester 2008-10-15 04:42.

それはすべてあなたがどれだけ正確になりたいかによります。私の目的では、bob @ aol.com(メール内のスペース)、steve(ドメインがまったく[email protected]ない)、(。comの前にピリオドがない)などを避けようとしている場合は、

/^\[email protected]\S+\.\S+$/

確かに、それは有効な電子メールアドレスではないものと一致しますが、それは一般的な単純なエラーを取得する問題です。

その正規表現に加えることができる変更はいくつもありますが(一部はこの回答のコメントにあります)、それは単純で理解しやすく、最初の試みとしては問題ありません。

345
Good Person 2009-04-06 09:39.

それはあなたが最もよく意味することによって異なります:あなたがすべての有効な電子メールアドレスをキャッチすることについて話しているなら、以下を使用してください:

(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:
\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(
?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ 
\t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\0
31]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\
](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+
(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:
(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)
?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\
r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[
 \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)
?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t]
)*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[
 \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*
)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)
*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+
|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r
\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t
]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031
]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](
?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?
:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?
:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?
:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?
[ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] 
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|
\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>
@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"
(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t]
)*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?
:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[
\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-
\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(
?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;
:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([
^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\"
.\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\
]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\
[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\
r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] 
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]
|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \0
00-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\
.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,
;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?
:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[
^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]
]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)(?:,\s*(
?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(
?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[
\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t
])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t
])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?
:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|
\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:
[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\
]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)
?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["
()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)
?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>
@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[
 \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,
;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t]
)*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:
\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[
"()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])
*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])
+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\
.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(
?:\r\n)?[ \t])*))*)?;\s*)

((http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html)もっと簡単なものを探しているが、それが最も有効な電子メールアドレスをキャッチする場合は、次のようなものを試してください。

"^[a-zA-Z0-9_.+-][email protected][a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$"

編集:リンクから:

この正規表現は、コメントが削除されて空白に置き換えられたアドレスのみを検証します(これはモジュールによって行われます)。

288
Dominic Sayers 2009-02-11 06:13.

[更新]メールアドレスの検証について知っていることをすべてここにまとめました。 http://isemail.info、電子メールアドレスの問題を検証するだけでなく診断するようになりました。検証は答えの一部にすぎないというここでのコメントの多くに同意します。で私のエッセイを参照してくださいhttp://isemail.info/about。

is_email()は、私が知る限り、指定された文字列が有効な電子メールアドレスであるかどうかを明確に通知する唯一のバリデーターのままです。新しいバージョンをでアップロードしましたhttp://isemail.info/

Cal Henderson、Dave Child、Phil Haack、Doug Lovell、RFC5322、RFC3696のテストケースを照合しました。全部で275のテストアドレス。私は、見つけたすべての無料のバリデーターに対してこれらすべてのテストを実行しました。

人々がバリデーターを強化するので、私はこのページを最新の状態に保つように努めます。Cal、Michael、Dave、Paul、Philの協力と、これらのテストの編集における協力と、私自身のバリデーターに対する建設的な批判に感謝します。

人々は特にRFC3696に対する正誤表に注意する必要があります。正規の例のうち3つは、実際には無効なアドレスです。また、アドレスの最大長は、320文字ではなく254文字または256文字です。

276
Rory O'Kane 2012-01-12 16:24.

パーW3C HTML5仕様:

^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-][email protected][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])?)*$

環境:

有効な電子メールアドレスは、 ABNF生産[...]を一致する文字列です。

注:この要件は、RFC 5322の故意の違反です。RFC5322は、厳密すぎる(「@」文字の前)、あいまいすぎる(「@」文字の後)、および緩すぎる(「@」文字の後)電子メールアドレスの構文を定義しています。ここでは、コメント、空白文字、引用符で囲まれた文字列を、ほとんどのユーザーにはなじみのない方法で使用できるようにします。

次のJavaScriptおよびPerl互換の正規表現は、上記の定義の実装です。

/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-][email protected][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])?)*$/

201
Abigail 2009-12-17 11:44.

Perl5.10以降では簡単です。

/(?(DEFINE)
   (?<address>         (?&mailbox) | (?&group))
   (?<mailbox>         (?&name_addr) | (?&addr_spec))
   (?<name_addr>       (?&display_name)? (?&angle_addr))
   (?<angle_addr>      (?&CFWS)? < (?&addr_spec) > (?&CFWS)?)
   (?<group>           (?&display_name) : (?:(?&mailbox_list) | (?&CFWS))? ;
                                          (?&CFWS)?)
   (?<display_name>    (?&phrase))
   (?<mailbox_list>    (?&mailbox) (?: , (?&mailbox))*)

   (?<addr_spec>       (?&local_part) \@ (?&domain))
   (?<local_part>      (?&dot_atom) | (?&quoted_string))
   (?<domain>          (?&dot_atom) | (?&domain_literal))
   (?<domain_literal>  (?&CFWS)? \[ (?: (?&FWS)? (?&dcontent))* (?&FWS)?
                                 \] (?&CFWS)?)
   (?<dcontent>        (?&dtext) | (?&quoted_pair))
   (?<dtext>           (?&NO_WS_CTL) | [\x21-\x5a\x5e-\x7e])

   (?<atext>           (?&ALPHA) | (?&DIGIT) | [!#\$%&'*+-/=?^_`{|}~])
   (?<atom>            (?&CFWS)? (?&atext)+ (?&CFWS)?)
   (?<dot_atom>        (?&CFWS)? (?&dot_atom_text) (?&CFWS)?)
   (?<dot_atom_text>   (?&atext)+ (?: \. (?&atext)+)*)

   (?<text>            [\x01-\x09\x0b\x0c\x0e-\x7f])
   (?<quoted_pair>     \\ (?&text))

   (?<qtext>           (?&NO_WS_CTL) | [\x21\x23-\x5b\x5d-\x7e])
   (?<qcontent>        (?&qtext) | (?&quoted_pair))
   (?<quoted_string>   (?&CFWS)? (?&DQUOTE) (?:(?&FWS)? (?&qcontent))*
                        (?&FWS)? (?&DQUOTE) (?&CFWS)?)

   (?<word>            (?&atom) | (?&quoted_string))
   (?<phrase>          (?&word)+)

   # Folding white space
   (?<FWS>             (?: (?&WSP)* (?&CRLF))? (?&WSP)+)
   (?<ctext>           (?&NO_WS_CTL) | [\x21-\x27\x2a-\x5b\x5d-\x7e])
   (?<ccontent>        (?&ctext) | (?&quoted_pair) | (?&comment))
   (?<comment>         \( (?: (?&FWS)? (?&ccontent))* (?&FWS)? \) )
   (?<CFWS>            (?: (?&FWS)? (?&comment))*
                       (?: (?:(?&FWS)? (?&comment)) | (?&FWS)))

   # No whitespace control
   (?<NO_WS_CTL>       [\x01-\x08\x0b\x0c\x0e-\x1f\x7f])

   (?<ALPHA>           [A-Za-z])
   (?<DIGIT>           [0-9])
   (?<CRLF>            \x0d \x0a)
   (?<DQUOTE>          ")
   (?<WSP>             [\x20\x09])
 )

 (?&address)/x
166
Per Hornshøj-Schierbeck 2008-10-15 04:17.

私が使う

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

これは、RegularExpressionValidatorによってASP.NETで使用されるものです。

142
Christian Vest Hansen 2008-10-15 04:17.

最善の方法はわかりませんが、アドレスのコメントが削除されて空白に置き換えられている限り、これは少なくとも正しいものです。

真剣に。電子メールの検証には、すでに作成されているライブラリを使用する必要があります。最善の方法は、おそらくそのアドレスに確認メールを送信することです。

111
davcar 2009-01-03 05:29.

検証したい電子メールアドレスは、System.Net.Mail名前空間を使用してASP.NET Webアプリケーションによって使用され、人々のリストに電子メールを送信します。

したがって、非常に複雑な正規表現を使用するのではなくMailAddress、アドレスからインスタンスを作成しようとします。MailAddressアドレスが適切に形成されていない場合、コンストラクタが例外をスローします。このようにして、私は少なくともメールをドアの外に出すことができることを知っています。もちろん、これはサーバー側の検証ですが、少なくともそれが必要です。

protected void emailValidator_ServerValidate(object source, ServerValidateEventArgs args)
{
    try
    {
        var a = new MailAddress(txtEmail.Text);
    }
    catch (Exception ex)
    {
        args.IsValid = false;
        emailValidator.ErrorMessage = "email: " + ex.Message;
    }
}
110
Rinke 2012-12-29 11:07.

素早い回答

入力検証には次の正規表現を使用します。

([-!#-'*+/-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])?)+

この正規表現に一致するアドレス:

  • RFC 5321/5322に厳密に準拠しているローカル部分(つまり、@記号の前の部分)があります。
  • 少なくとも2つのラベルが付いたホスト名であるドメイン部分(つまり、@記号の後の部分)があり、それぞれの長さは最大63文字です。

2番目の制約は、RFC5321 / 5322の制限です。

手の込んだ答え

電子メールアドレスを認識する正規表現を使用すると、さまざまな状況で役立つ可能性があります。たとえば、ドキュメント内の電子メールアドレスをスキャンしたり、ユーザー入力を検証したり、データリポジトリの整合性制約として使用したりできます。

ただし、アドレスが実際に既存のメールボックスを参照しているかどうかを確認する場合は、そのアドレスにメッセージを送信する以外に方法がないことに注意してください。アドレスが文法的に正しいかどうかだけを確認したい場合は、正規表現を使用できますが、それ""@[]は文法的に正しい電子メールアドレスであり、既存のメールボックスを確実に参照していないことに注意してください。

電子メールアドレスの構文は、さまざまなRFC、特にRFC822およびRFC5322で定義されています。RFC 822は「元の」標準と見なされ、RFC5322は最新の標準と見なされます。RFC 822で定義されている構文は最も寛大であり、その後の標準では構文がさらに制限されており、新しいシステムまたはサービスは廃止された構文を認識しますが、生成することはありません。

この回答では、「電子メールアドレス」をaddr-specRFCで定義されている意味と解釈します(つまり[email protected]、ではなく"John Doe"<[email protected]>、またはsome-group:[email protected],[email protected];)。

RFC構文を正規表現に変換することには1つの問題があります。それは、構文が規則的ではないということです。これは、無限にネストできる電子メールアドレスでオプションのコメントを許可するのに対し、無限のネストは正規表現で記述できないためです。コメントを含むアドレスをスキャンまたは検証するには、パーサーまたはより強力な式が必要です。(Perlのような言語には、文脈自由文法を正規表現のように記述するための構造があることに注意してください。)この回答では、コメントを無視し、適切な正規表現のみを検討します。

RFCは、電子メールアドレス自体ではなく、電子メールメッセージの構文を定義します。アドレスはさまざまなヘッダーフィールドに表示される場合があり、ここで主に定義されます。それらがヘッダーフィールドに表示される場合、アドレスには(字句トークンの間に)空白、コメント、さらには改行が含まれる場合があります。ただし、意味的にはこれは重要ではありません。この空白などをアドレスから削除することにより、意味的に同等の正規表現を取得します。したがって、の正規表現はfirst. last (comment) @ [3.5.7.9]です[email protected][3.5.7.9]

目的ごとに異なる構文を使用する必要があります。(おそらく非常に古い)ドキュメント内の電子メールアドレスをスキャンする場合は、RFC 822で定義されている構文を使用することをお勧めします。一方、ユーザー入力を検証する場合は、 RFC 5322で定義されている構文で、おそらく正規の表現のみを受け入れます。特定のケースに適用する構文を決定する必要があります。

この回答では、ASCII互換の文字セットを想定して、POSIXの「拡張」正規表現を使用しています。

RFC 822

次の正規表現にたどり着きました。私は皆にそれを壊してみることを勧めます。誤検知や誤検知を見つけた場合は、コメントに投稿してください。できるだけ早く表現を修正するよう努めます。

([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*")(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*"))*@([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*])(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*]))*

正誤表を含むRFC822に完全に準拠していると思います。正規の形式の電子メールアドレスのみを認識します。空白を認識する(折りたたむ)正規表現については、以下の派生を参照してください。

派生は、私がどのようにして表現に到達したかを示しています。RFCの関連するすべての文法規則を、表示されているとおりに正確にリストし、その後に対応する正規表現をリストします。正誤表が公開されている場合は、修正された文法規則(「正誤表」とマークされている)に別の式を指定し、更新されたバージョンを後続の正規表現の部分式として使用します。

3.1.4項で述べたように。RFC 822のオプションの線形空白は、字句トークンの間に挿入できます。該当する場合は、このルールに対応するように式を拡張し、結果に「opt-lwsp」のマークを付けました。

CHAR        =  <any ASCII character>
            =~ .

CTL         =  <any ASCII control character and DEL>
            =~ [\x00-\x1F\x7F]

CR          =  <ASCII CR, carriage return>
            =~ \r

LF          =  <ASCII LF, linefeed>
            =~ \n

SPACE       =  <ASCII SP, space>
            =~  

HTAB        =  <ASCII HT, horizontal-tab>
            =~ \t

<">         =  <ASCII quote mark>
            =~ "

CRLF        =  CR LF
            =~ \r\n

LWSP-char   =  SPACE / HTAB
            =~ [ \t]

linear-white-space =  1*([CRLF] LWSP-char)
                   =~ ((\r\n)?[ \t])+

specials    =  "(" / ")" / "<" / ">" / "@" /  "," / ";" / ":" / "\" / <"> /  "." / "[" / "]"
            =~ [][()<>@,;:\\".]

quoted-pair =  "\" CHAR
            =~ \\.

qtext       =  <any CHAR excepting <">, "\" & CR, and including linear-white-space>
            =~ [^"\\\r]|((\r\n)?[ \t])+

dtext       =  <any CHAR excluding "[", "]", "\" & CR, & including linear-white-space>
            =~ [^][\\\r]|((\r\n)?[ \t])+

quoted-string  =  <"> *(qtext|quoted-pair) <">
               =~ "([^"\\\r]|((\r\n)?[ \t])|\\.)*"
(erratum)      =~ "(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*"

domain-literal =  "[" *(dtext|quoted-pair) "]"
               =~ \[([^][\\\r]|((\r\n)?[ \t])|\\.)*]
(erratum)      =~ \[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]

atom        =  1*<any CHAR except specials, SPACE and CTLs>
            =~ [^][()<>@,;:\\". \x00-\x1F\x7F]+

word        =  atom / quoted-string
            =~ [^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*"

domain-ref  =  atom

sub-domain  =  domain-ref / domain-literal
            =~ [^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]

local-part  =  word *("." word)
            =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*")(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*"))*
(opt-lwsp)  =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*")(((\r\n)?[ \t])*\.((\r\n)?[ \t])*([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*"))*

domain      =  sub-domain *("." sub-domain)
            =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*])(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]))*
(opt-lwsp)  =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*])(((\r\n)?[ \t])*\.((\r\n)?[ \t])*([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]))*

addr-spec   =  local-part "@" domain
            =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*")(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*"))*@([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*])(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]))*
(opt-lwsp)  =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*")((\r\n)?[ \t])*(\.((\r\n)?[ \t])*([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*")((\r\n)?[ \t])*)*@((\r\n)?[ \t])*([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*])(((\r\n)?[ \t])*\.((\r\n)?[ \t])*([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]|(\r\n)?[ \t]))*(\\\r)*]))*
(canonical) =~ ([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*")(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*"))*@([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*])(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*]))*

RFC 5322

次の正規表現にたどり着きました。私は皆にそれを壊してみることを勧めます。誤検知や誤検知を見つけた場合は、コメントに投稿してください。できるだけ早く表現を修正するよう努めます。

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

正誤表を含むRFC5322に完全に準拠していると思います。正規の形式の電子メールアドレスのみを認識します。空白を認識する(折りたたむ)正規表現については、以下の派生を参照してください。

派生は、私がどのようにして表現に到達したかを示しています。RFCの関連するすべての文法規則を、表示されているとおりに正確にリストし、その後に対応する正規表現をリストします。意味的に無関係な(折りたたみ)空白を含むルールの場合、この空白を受け入れない「(正規化)」とマークされた別の正規表現を指定します。

RFCのすべての「obs-」ルールを無視しました。これは、正規表現が厳密にRFC5322に準拠している電子メールアドレスにのみ一致することを意味します。「古い」アドレスを一致させる必要がある場合(「obs-」ルールを含むより緩い文法のように)、前の段落のRFC822正規表現の1つを使用できます。

VCHAR           =   %x21-7E
                =~  [!-~]

ALPHA           =   %x41-5A / %x61-7A
                =~  [A-Za-z]

DIGIT           =   %x30-39
                =~  [0-9]

HTAB            =   %x09
                =~  \t

CR              =   %x0D
                =~  \r

LF              =   %x0A
                =~  \n

SP              =   %x20
                =~  

DQUOTE          =   %x22
                =~  "

CRLF            =   CR LF
                =~  \r\n

WSP             =   SP / HTAB
                =~  [\t ]

quoted-pair     =   "\" (VCHAR / WSP)
                =~  \\[\t -~]

FWS             =   ([*WSP CRLF] 1*WSP)
                =~  ([\t ]*\r\n)?[\t ]+

ctext           =   %d33-39 / %d42-91 / %d93-126
                =~  []!-'*-[^-~]

("comment" is left out in the regex)
ccontent        =   ctext / quoted-pair / comment
                =~  []!-'*-[^-~]|(\\[\t -~])

(not regular)
comment         =   "(" *([FWS] ccontent) [FWS] ")"

(is equivalent to FWS when leaving out comments)
CFWS            =   (1*([FWS] comment) [FWS]) / FWS
                =~  ([\t ]*\r\n)?[\t ]+

atext           =   ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~"
                =~  [-!#-'*+/-9=?A-Z^-~]

dot-atom-text   =   1*atext *("." 1*atext)
                =~  [-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*

dot-atom        =   [CFWS] dot-atom-text [CFWS]
                =~  (([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?
(normalized)    =~  [-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*

qtext           =   %d33 / %d35-91 / %d93-126
                =~  []!#-[^-~]

qcontent        =   qtext / quoted-pair
                =~  []!#-[^-~]|(\\[\t -~])

(erratum)
quoted-string   =   [CFWS] DQUOTE ((1*([FWS] qcontent) [FWS]) / FWS) DQUOTE [CFWS]
                =~  (([\t ]*\r\n)?[\t ]+)?"(((([\t ]*\r\n)?[\t ]+)?([]!#-[^-~]|(\\[\t -~])))+(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?)"(([\t ]*\r\n)?[\t ]+)?
(normalized)    =~  "([]!#-[^-~ \t]|(\\[\t -~]))+"

dtext           =   %d33-90 / %d94-126
                =~  [!-Z^-~]

domain-literal  =   [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
                =~  (([\t ]*\r\n)?[\t ]+)?\[((([\t ]*\r\n)?[\t ]+)?[!-Z^-~])*(([\t ]*\r\n)?[\t ]+)?](([\t ]*\r\n)?[\t ]+)?
(normalized)    =~  \[[\t -Z^-~]*]

local-part      =   dot-atom / quoted-string
                =~  (([\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 ]+)?
(normalized)    =~  [-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+"

domain          =   dot-atom / domain-literal
                =~  (([\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 ]+)?
(normalized)    =~  [-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\[[\t -Z^-~]*]

addr-spec       =   local-part "@" domain
                =~  ((([\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 ]+)?)
(normalized)    =~  ([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\[[\t -Z^-~]*])

一部のソース(特にw3c)は、RFC 5322がローカル部分(つまり、@記号の前の部分)に対して厳しすぎると主張していることに注意してください。これは、「..」、「a..b」、「a。」が原因です。メールボックス名として使用される可能性がありますが、有効なドットアトムではありません。RFCは、しかし、ないそれらが引用されたことをしていることを除いて、これらのような地元の部品を可能にします。したがって、代わりに、意味的に同等のを[email protected]書く必要があります"a..b"@example.net

さらなる制限

SMTP(RFC 5321で定義されている)は、有効な電子メールアドレスのセット(または実際にはメールボックス名)をさらに制限します。一致した電子メールアドレスを実際に使用して電子メールを送信できるように、このより厳密な文法を課すことは合理的と思われます。

RFC 5321は基本的に「ローカル」部分(つまり、@記号の前の部分)をそのままにしますが、ドメイン部分(つまり、@記号の後の部分)ではより厳密です。ドットアトムの代わりにホスト名のみを許可し、ドメインリテラルの代わりにアドレスリテラルを許可します。

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

([-!#-'*+/-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^-~]+)])

ユースケースによっては、正規表現で「General-address-literal」を許可したくない場合があることに注意してください。また(?!IPv6:)、「General-address-literal」の部分が不正な形式のIPv6アドレスと一致するのを防ぐために、最終正規表現で負の先読みを使用したことにも注意してください。一部の正規表現プロセッサは、ネガティブルックアヘッドをサポートしていません。|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+「General-address-literal」の部分全体を削除する場合は、正規表現から部分文字列を削除します。

派生は次のとおりです。

Let-dig         =   ALPHA / DIGIT
                =~  [0-9A-Za-z]

Ldh-str         =   *( ALPHA / DIGIT / "-" ) Let-dig
                =~  [0-9A-Za-z-]*[0-9A-Za-z]

(regex is updated to make sure sub-domains are max. 63 charactes long - RFC 1034 section 3.5)
sub-domain      =   Let-dig [Ldh-str]
                =~  [0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?

Domain          =   sub-domain *("." sub-domain)
                =~  [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])?)*

Snum            =   1*3DIGIT
                =~  [0-9]{1,3}

(suggested replacement for "Snum")
ip4-octet       =   DIGIT / %x31-39 DIGIT / "1" 2DIGIT / "2" %x30-34 DIGIT / "25" %x30-35
                =~  25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]

IPv4-address-literal    =   Snum 3("."  Snum)
                        =~  [0-9]{1,3}(\.[0-9]{1,3}){3}

(suggested replacement for "IPv4-address-literal")
ip4-address     =   ip4-octet 3("." ip4-octet)
                =~  (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}

(suggested replacement for "IPv6-hex")
ip6-h16         =   "0" / ( (%x49-57 / %x65-70 /%x97-102) 0*3(%x48-57 / %x65-70 /%x97-102) )
                =~  0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}

(not from RFC)
ls32            =   ip6-h16 ":" ip6-h16 / ip4-address
                =~  (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}

(suggested replacement of "IPv6-addr")
ip6-address     =                                      6(ip6-h16 ":") ls32
                    /                             "::" 5(ip6-h16 ":") ls32
                    / [                 ip6-h16 ] "::" 4(ip6-h16 ":") ls32
                    / [ *1(ip6-h16 ":") ip6-h16 ] "::" 3(ip6-h16 ":") ls32
                    / [ *2(ip6-h16 ":") ip6-h16 ] "::" 2(ip6-h16 ":") ls32
                    / [ *3(ip6-h16 ":") ip6-h16 ] "::"   ip6-h16 ":"  ls32
                    / [ *4(ip6-h16 ":") ip6-h16 ] "::"                ls32
                    / [ *5(ip6-h16 ":") ip6-h16 ] "::"   ip6-h16
                    / [ *6(ip6-h16 ":") ip6-h16 ] "::"
                =~  (((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-address-literal    =   "IPv6:" ip6-address
                        =~  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}))?::)

Standardized-tag        =   Ldh-str
                        =~  [0-9A-Za-z-]*[0-9A-Za-z]

dcontent        =   %d33-90 / %d94-126
                =~  [!-Z^-~]

General-address-literal =   Standardized-tag ":" 1*dcontent
                        =~  [0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+

address-literal =   "[" ( IPv4-address-literal / IPv6-address-literal / General-address-literal ) "]"
                =~  \[((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^-~]+)]

Mailbox         =   Local-part "@" ( Domain / address-literal )
                =~  ([-!#-'*+/-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^-~]+)])

ユーザー入力の検証

一般的な使用例は、たとえばhtmlフォームでのユーザー入力の検証です。その場合、通常、アドレスリテラルを除外し、ホスト名に少なくとも2つのラベルを要求するのが妥当です。前のセクションから改善されたRFC5321正規表現を基礎として使用すると、結果の式は次のようになります。

([-!#-'*+/-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])?)+

我々はいくつかのホストが(のような許可メールボックス名の種類がわからないので、私は、引用符で囲まれた文字列を排除することにより、例えば、さらに地元の一部を制限することはお勧めしません"a..b"@example.netかさえも"a b"@example.net)。

また、リテラルのトップレベルドメインのリストに対して明示的に検証したり、長さの制約を課したりすることもお勧めしません( ".museum"がどのように無効化されたかを覚えておい[a-z]{2,4}てください)。

([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?\.)*(net|org|com|info|等...)

明示的なトップレベルドメイン検証のパスをたどる場合は、正規表現を最新の状態に保つようにしてください。

さらなる考慮事項

ドメイン部分(@記号の後)でホスト名のみを受け入れる場合、上記の正規表現は、必要に応じて、最大63文字のラベルのみを受け入れます。ただし、ホスト名全体の長さが最大253文字(ドットを含む)でなければならないという事実は強制されません。この制約は厳密に言えばまだ規則的ですが、このルールを組み込んだ正規表現を作成することは現実的ではありません。

特に入力検証に正規表現を使用する場合のもう1つの考慮事項は、ユーザーへのフィードバックです。ユーザーが間違ったアドレスを入力した場合は、単純な「構文的に間違ったアドレス」よりも少し多くのフィードバックを提供するとよいでしょう。「バニラ」正規表現では、これは不可能です。

これらの2つの考慮事項は、アドレスを解析することで対処できます。ホスト名の余分な長さの制約は、それをチェックする余分な正規表現を使用し、アドレスを両方の式と照合することによって対処できる場合もあります。

この回答の正規表現はいずれも、パフォーマンスが最適化されていません。パフォーマンスが問題になる場合は、選択した正規表現を最適化できるかどうか(およびその方法)を確認する必要があります。

73
Draemon 2008-10-15 04:18.

ネット上にはこれの例がたくさんあります(そしてRFCを完全に検証するものでもあると思いますが、メモリが機能する場合は数十/数百行の長さです)。人々はこの種のことを検証することに夢中になりがちです。@と少なくとも1つあることを確認してみませんか。いくつかの単純な最小の長さを満たしています。偽の電子メールを入力しても、とにかく有効な正規表現と一致するのは簡単です。誤検知は誤検知よりも優れていると思います。

65
DOK 2008-10-15 06:19.

許可する文字を決定するときは、使徒職とハイフンでつながれた友達を覚えておいてください。私の会社が人事システムから私の名前を使用して私の電子メールアドレスを生成するという事実を制御することはできません。これには、私の姓のアポストロフィが含まれます。私のメールアドレスが「無効」であるために、ウェブサイトとのやり取りがブロックされた回数はわかりません。

62
Evan Carroll 2010-01-28 06:43.

この正規表現は、PerlのEmail :: Validライブラリからのものです。私はそれが最も正確であると信じています、それはすべての822に一致します。そして、それはオライリーの本の正規表現に基づいています:

正規表現の習得におけるジェフリー・フリードルの例を使用して構築された正規表現(http://www.ora.com/catalog/regexp/)。

$RFC822PAT = <<'EOF';
[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\
xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xf
f\n\015()]*)*\)[\040\t]*)*(?:(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\x
ff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015
"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\
xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80
-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*
)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\
\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\
x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x8
0-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n
\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x
80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^
\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040
\t]*)*)*@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([
^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\
\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\
x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-
\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()
]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\
x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\04
0\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\
n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\
015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?!
[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\
]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\
x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\01
5()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*|(?:[^(\040)<>@,;:".
\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]
)|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^
()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037]*(?:(?:\([^\\\x80-\xff\n\0
15()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][
^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)|"[^\\\x80-\xff\
n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^()<>@,;:".\\\[\]\
x80-\xff\000-\010\012-\037]*)*<[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?
:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-
\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:@[\040\t]*
(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015
()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()
]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\0
40)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\
[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\
xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*
)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80
-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x
80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t
]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\
\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])
*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x
80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80
-\xff\n\015()]*)*\)[\040\t]*)*)*(?:,[\040\t]*(?:\([^\\\x80-\xff\n\015(
)]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\
\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*@[\040\t
]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\0
15()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015
()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(
\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|
\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80
-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()
]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x
80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^
\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040
\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".
\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff
])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\
\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x
80-\xff\n\015()]*)*\)[\040\t]*)*)*)*:[\040\t]*(?:\([^\\\x80-\xff\n\015
()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\
\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)?(?:[^
(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-
\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\
n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|
\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))
[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff
\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\x
ff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(
?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\
000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\
xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\x
ff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)
*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*@[\040\t]*(?:\([^\\\x80-\x
ff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-
\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)
*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\
]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\]
)[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-
\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\x
ff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(
?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80
-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<
>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x8
0-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:
\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]
*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)
*\)[\040\t]*)*)*>)
EOF
46
SimonSimCity 2011-12-21 22:40.

PHPで書いているので、電子メールにはPHP組み込み検証を使用することをお勧めします。

filter_var($value, FILTER_VALIDATE_EMAIL)

5.3.6より前のphpバージョンを実行している場合は、次の問題に注意してください。 https://bugs.php.net/bug.php?id=53091

このビルトイン検証がどのように機能するかについての詳細が必要な場合は、ここを参照してください:PHPのfilter_var FILTER_VALIDATE_EMAILは実際に機能しますか?

43
adnam 2008-10-15 06:35.

Cal Henderson(Flickr)は、PHPでの電子メールアドレスの解析と呼ばれる記事を書き、RFC(2)822に準拠した適切な電子メールアドレスの解析を行う方法を示しています。ソースコードは、php、python、およびccライセンスのrubyで入手することもできます。

42
Kon 2008-10-15 04:23.

他の誰かがすでにより良いバージョンを考え出している可能性があるので、私は自分の正規表現で作成することを決して気にしません。私はいつもregexlibを使って好きなものを見つけます。

37
PhiLho 2008-10-15 05:38.

本当に使えるものはありません。メールアドレス検証用のphpライブラリはありますか?への回答で
いくつかの問題について説明します。、メールアドレスの正規表現認識でも議論されていますか?

要するに、単一の使用可能な正規表現が適切な仕事をすることを期待しないでください。そして、最良の正規表現は、電子メールの有効性ではなく、構文を検証します([email protected]は正しいですが、おそらくバウンスします...)。

36
spig 2009-10-23 11:54.

少なくとも有効な電子メールアドレスを拒否しない単純な正規表現の1つは、何かをチェックし、その後に@記号を付け、次に何かを続け、その後にピリオドと少なくとも2つの何かをチェックすることです。何も拒否されませんが、仕様を確認した後、有効で拒否されるメールが見つかりません。

メール=〜 /[email protected][^@]+\.[^@]{2,}$/

29
chaos 2009-05-24 08:22.

jQueryValidationプラグインで採用されているものを使用できます。

/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i
25
Eric Schoonover 2010-05-29 12:03.

電子メールアドレスを検証するための最良の正規表現の最も包括的な評価については、このリンクを参照してください。「正規表現を検証する電子メールアドレスの比較」

参照用の現在の上位式は次のとおりです。

/^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~][email protected]((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i
23
BalusC 2009-12-19 13:40.

ラテン語以外(中国語、アラビア語、ギリシャ語、ヘブライ語、キリル文字など)のドメイン名は、近い将来許可されることは言うまでもありません。これらの文字は確かに[a-z]/inorでカバーされないため、使用する電子メールの正規表現を変更する必要があります\w。それらはすべて失敗します。

結局のところ、最高の電子メールアドレスを検証するための方法は、実際にはまだある送信アドレスを検証するために、問題のアドレスに電子メールを。メールアドレスがユーザー認証(登録/ログインなど)の一部である場合は、ユーザーアクティベーションシステムと完全に組み合わせることができます。つまり、指定されたメールアドレスに一意のアクティベーションキーを持つリンクを含むメールを送信し、ユーザーがメール内のリンクを使用して新しく作成されたアカウントをアクティベートした場合にのみログインを許可します。

正規表現の目的が、指定された電子メールアドレスが正しい形式ではないことをUIでユーザーにすばやく通知することである場合でも、基本的に次の正規表現と一致するかどうかを確認するのが最善です。

^([^[email protected]]+)(\.[^[email protected]]+)*@([^[email protected]]+\.)+([^[email protected]]+)$

そのような単純な。名前とドメインで使用されている文字を気にするのはなぜですか?サーバーのアドレスではなく、有効な電子メールアドレスを入力するのはクライアントの責任です。クライアントがのような構文的に有効な電子メールアドレスを入力した場合でも[email protected]、これはそれが正当な電子メールアドレスであることを保証するものではありません。誰もそれをカバーすることはできません。

20
Ross Allan 2015-08-15 02:30.

HTML5の仕様では、提案する電子メールアドレスを検証するための簡単な正規表現を:

/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-][email protected][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])?)*$/

これは意図的にRFC5322に準拠していません。

注:この要件はRFC 5322の故意の違反であり、電子メールアドレスの構文を定義しますこの構文では、厳密すぎる(文字の前)、あいまいすぎる(文字の後)、緩すぎる(コメント、空白文字、そして、ほとんどのユーザーにはなじみのない方法で引用された文字列)がここで実用的です。@@

RFC 3696 errata 1690に従って、全長を254文字に制限することもできます。

16
Greg Bacon 2009-06-26 05:15.

鮮やかなデモンストレーションの場合、次のモンスターはかなり優れていますが、構文的に有効なすべての電子メールアドレスを正しく認識しません。最大4レベルの深さのネストされたコメントを認識します。

これはパーサーの仕事ですが、アドレスが構文的に有効であっても、配信できない場合があります。時々、あなたは「ねえ、みんな、ee-usを見て!」というヒルビリーの方法に頼らなければならない。

// derivative of work with the following copyright and license:
// Copyright (c) 2004 Casey West.  All rights reserved.
// This module is free software; you can redistribute it and/or
// modify it under the same terms as Perl itself.

// see http://search.cpan.org/~cwest/Email-Address-1.80/

private static string gibberish = @"
(?-xism:(?:(?-xism:(?-xism:(?-xism:(?-xism:(?-xism:(?-xism:\
s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^
\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))
|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+
|\s+)*[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+(?-xism:(?-xism:\
s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^
\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))
|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+
|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(
?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?
:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x
0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*<DQ>(?-xism:(?-xism:[
^\\<DQ>])|(?-xism:\\(?-xism:[^\x0A\x0D])))+<DQ>(?-xism:(?-xi
sm:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xis
m:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\
]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\
s*)+|\s+)*))+)?(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?
-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:
\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[
^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*<(?-xism:(?-xi
sm:(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^(
)\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(
?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))
|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()<
>\[\]:;@\,.<DQ>\s]+(?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]
+)*)(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))
|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:
(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s
*\)\s*))+)*\s*\)\s*)+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?
:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x
0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xi
sm:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*
<DQ>(?-xism:(?-xism:[^\\<DQ>])|(?-xism:\\(?-xism:[^\x0A\x0D]
)))+<DQ>(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\
]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-x
ism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+
)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*))\@(?-xism:(?-xism:(?-xism:(
?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?
-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^
()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s
*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+(
?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+)*)(?-xism:(?-xism:
\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[
^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+)
)|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)
+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:
(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((
?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\
x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*\[(?:\s*(?-xism:(?-x
ism:[^\[\]\\])|(?-xism:\\(?-xism:[^\x0A\x0D])))+)*\s*\](?-xi
sm:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:
\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(
?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+
)*\s*\)\s*)+|\s+)*)))>(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-
xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\
s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^
\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*))|(?-xism:(?-x
ism:(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^
()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*
(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D])
)|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()
<>\[\]:;@\,.<DQ>\s]+(?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s
]+)*)(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+)
)|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism
:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\
s*\)\s*))+)*\s*\)\s*)+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((
?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\
x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-x
ism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)
*<DQ>(?-xism:(?-xism:[^\\<DQ>])|(?-xism:\\(?-xism:[^\x0A\x0D
])))+<DQ>(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\
\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-
xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)
+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*))\@(?-xism:(?-xism:(?-xism:
(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(
?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[
^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\
s*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+
(?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+)*)(?-xism:(?-xism
:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:
[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+
))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*
)+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism
:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\(
(?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A
\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*\[(?:\s*(?-xism:(?-
xism:[^\[\]\\])|(?-xism:\\(?-xism:[^\x0A\x0D])))+)*\s*\](?-x
ism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism
:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:
(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))
+)*\s*\)\s*)+|\s+)*))))(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?
>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:
\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0
D]))|)+)*\s*\)\s*))+)*\s*\)\s*)*)"
  .Replace("<DQ>", "\"")
  .Replace("\t", "")
  .Replace(" ", "")
  .Replace("\r", "")
  .Replace("\n", "");

private static Regex mailbox =
  new Regex(gibberish, RegexOptions.ExplicitCapture); 
12
AZ_ 2010-12-30 02:58.

公式標準RFC2822によると、有効な電子メール正規表現は

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

Javaで使用したい場合は、非常に簡単です。

import java.util.regex.*;

class regexSample 
{
   public static void main(String args[]) 
   {
      //Input the string for validation
      String email = "[email protected]";

      //Set the email pattern string
      Pattern p = Pattern.compile(" (?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"
              +"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")"
                     + "@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\]");

      //Match the given string with the pattern
      Matcher m = p.matcher(email);

      //check whether match is found 
      boolean matchFound = m.matches();

      if (matchFound)
        System.out.println("Valid Email Id.");
      else
        System.out.println("Invalid Email Id.");
   }
}
11
Mac 2011-07-20 17:37.

これが私が使っているPHPです。ここで別のコメント提供者が宣言しているように、「誤検知は誤検知よりも優れている」という精神でこのソリューションを選択しました。応答時間の増加とサーバーの負荷の軽減に関しては、サーバーリソースを無駄にする必要はありません。これが最も単純なユーザーエラーを取り除くときの正規表現。必要に応じて、テストメールを送信していつでもフォローアップできます。

function validateEmail($email) { return (bool) stripos($email,'@');
}
11
MichaelRushton 2009-11-21 06:05.

RFC 5322標準:

dot-atom local-part、quoted-string local-part、廃止された(dot-atomとquoted-stringの混合)local-part、ドメイン名ドメイン、(IPv4、IPv6、およびIPv4マップIPv6アドレス)ドメインリテラルドメインを許可します。および(ネストされた)CFWS。

'/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD'

RFC 5321標準:

dot-atom local-part、quoted-string local-part、domain name domain、および(IPv4、IPv6、およびIPv4にマップされたIPv6アドレス)ドメインリテラルドメインを許可します。

'/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!"?(?>\\\[ -~]|[^"]){65,}"[email protected])(?>([!#-\'*+\/-9=?^-~-]+)(?>\.(?1))*|"(?>[ !#-\[\]-~]|\\\[ -~])*")@(?!.*[^.]{64,})(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?2)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?3)){7}|(?!(?:.*[a-f0-9][:\]]){8,})((?3)(?>:(?3)){0,6})?::(?4)?))|(?>(?>IPv6:(?>(?3)(?>:(?3)){5}:|(?!(?:.*[a-f0-9]:){6,})(?5)?::(?>((?3)(?>:(?3)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?6)){3}))\])$/iD'

基本:

ドットアトムローカルパーツおよびドメイン名ドメインを許可します(TLDが2〜6個のアルファベット文字に制限された少なくとも2つのドメイン名ラベルが必要です)。

"/^(?!.{255,})(?!.{65,}@)([!#-'*+\/-9=?^-~-]+)(?>\.(?1))*@(?!.*[^.]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?\.){1,126}[a-z]{2,6}$/iD"
8
TombMedia 2012-12-02 20:15.

私はあなたの正規表現のこの修正されたバージョンをしばらく使用してきました、そしてそれは私にあまり多くの驚きを残しませんでした。 メールでアポストロフィに遭遇したことはまだないので、それを検証しません 。それは検証Jean+Franç[email protected]します试@例子.测试.مثال.آزمایشیが、それらの英数字以外の文字の奇妙な乱用ではありません[email protected]

(?!^[.+&'_-]*@.*$)(^[_\w\d+&'-]+(\.[_\w\d+&'-]*)*@[\w\d-]+(\.[\w\d-]+)*\.(([\d]{1,3})|([\w]{2,}))$)

IPアドレスはサポートしています[email protected]が、などの偽のIP範囲を処理するために十分に改良していません999.999.999.1

また、3文字を超えるすべてのTLDをサポートしているため、元のTLD [email protected]は通過したと思います。 私は殴られてきました、今では3文字を超えるTLDが多すぎます。

アクロスマンが正規表現を放棄したことは知っていますが、このフレーバーは存続しています。

8
Prasad 2012-04-28 23:45.

空の値(無効な電子メールではありません)を受け入れて、PHP 5.2以降を実行している場合は、次のことをお勧めします。

static public function checkEmail($email, $ignore_empty = false) {
        if($ignore_empty && (is_null($email) || $email == '')) return true; return filter_var($email, FILTER_VALIDATE_EMAIL);
    }

Related questions

MORE COOL STUFF

Reba McEntire は、彼女が息子の Shelby Blackstock と共有する「楽しい」クリスマスの伝統を明らかにしました:「私たちはたくさん笑います」

Reba McEntire は、彼女が息子の Shelby Blackstock と共有する「楽しい」クリスマスの伝統を明らかにしました:「私たちはたくさん笑います」

Reba McEntire が息子の Shelby Blackstock と共有しているクリスマスの伝統について学びましょう。

メーガン・マークルは、自然な髪のスタイリングをめぐってマライア・キャリーと結ばれました

メーガン・マークルは、自然な髪のスタイリングをめぐってマライア・キャリーと結ばれました

メーガン・マークルとマライア・キャリーが自然な髪の上でどのように結合したかについて、メーガンの「アーキタイプ」ポッドキャストのエピソードで学びましょう.

ハリー王子は家族との関係を修復できるという「希望を持っている」:「彼は父親と兄弟を愛している」

ハリー王子は家族との関係を修復できるという「希望を持っている」:「彼は父親と兄弟を愛している」

ハリー王子が家族、特にチャールズ王とウィリアム王子との関係について望んでいると主張したある情報源を発見してください。

ワイノナ・ジャッドは、パニックに陥った休暇の瞬間に、彼女がジャッド家の家長であることを認識しました

ワイノナ・ジャッドは、パニックに陥った休暇の瞬間に、彼女がジャッド家の家長であることを認識しました

ワイノナ・ジャッドが、母親のナオミ・ジャッドが亡くなってから初めての感謝祭のお祝いを主催しているときに、彼女が今では家長であることをどのように認識したかを学びましょう.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

バレリー・ジャレットは類人猿と呼ばれ、ロザンヌ・バーは仕事を失いましたが、ここでの本当の犠牲者はトランプです

バレリー・ジャレットは類人猿と呼ばれ、ロザンヌ・バーは仕事を失いましたが、ここでの本当の犠牲者はトランプです

ロザンヌ・バーが自分自身でいるだけでABCショーの再起動を破壊するのに、60日強かかりました。ロザンヌは、ツイッターで帽子をかぶったトロールであり、白人至上主義者に傾倒し、陰謀論者を愛する「Make AmericaGreatAmerica」であり続けています。

「警察官」を使用して、ビジネス会議をトピックに保つ

「警察官」を使用して、ビジネス会議をトピックに保つ

仕事の打ち合わせをしていると、招待される人が多ければ多いほど、全体が狂いやすくなります。そのため、すべての打ち合わせには、話題を維持するための打ち合わせ「警察」が必要です。全員が集まって話し合う間今週終了する大きなプロジェクトについては、必然的に誰かが「私たちはみんなここにいるので…」と決めるでしょう。数週間後に起こっている別のプロジェクトを立ち上げるのは良い考えです。コーヒーメーカーはどうしたの?壊れていますか?そして、ジョンの新しい子犬を見たことがありますか?会話を中断して、10分間写真を見てみましょう。

黒人が記念日を作成—文字通り

黒人が記念日を作成—文字通り

記念日はここにあります。バーベキュー、レモネードを考えてください。

ドレイク、ネコケース、そしてカニエの大洪水:6月の38の最も期待されたアルバム

ドレイク、ネコケース、そしてカニエの大洪水:6月の38の最も期待されたアルバム

5月のリリースの特に強力なラインナップに続いて、6月はNeko Case、Nas、Lykke Li、Gang Gang Danceから待望のリターンをもたらし、Drake、Oneohtrix Point Never、Zeal&Ardourからの期待された努力とSnailMailからの有望なデビューをもたらしますとジュリアーナドーティ。ヒップホップでは、間違いなくカニエの月であり、ラッパープロデューサーは毎週少なくとも1回のリリースに関与しています。

米国のフィギュア スケートは、チーム イベントでの最終決定の欠如に「苛立ち」、公正な裁定を求める

米国のフィギュア スケートは、チーム イベントでの最終決定の欠如に「苛立ち」、公正な裁定を求める

ロシアのフィギュアスケーター、カミラ・バリエバが関与したドーピング事件が整理されているため、チームは2022年北京冬季オリンピックで獲得したメダルを待っています。

Amazonの買い物客は、わずか10ドルのシルクの枕カバーのおかげで、「甘やかされた赤ちゃんのように」眠れると言っています

Amazonの買い物客は、わずか10ドルのシルクの枕カバーのおかげで、「甘やかされた赤ちゃんのように」眠れると言っています

何千人ものAmazonの買い物客がMulberry Silk Pillowcaseを推奨しており、現在販売中. シルクの枕カバーにはいくつかの色があり、髪を柔らかく肌を透明に保ちます。Amazonで最大46%オフになっている間にシルクの枕カバーを購入してください

パデュー大学の教授が覚醒剤を扱った疑いで逮捕され、女性に性的好意を抱かせる

パデュー大学の教授が覚醒剤を扱った疑いで逮捕され、女性に性的好意を抱かせる

ラファイエット警察署は、「不審な男性が女性に近づいた」という複数の苦情を受けて、12 月にパデュー大学の教授の捜査を開始しました。

コンセプト ドリフト: AI にとって世界の変化は速すぎる

コンセプト ドリフト: AI にとって世界の変化は速すぎる

私たちの周りの世界と同じように、言語は常に変化しています。以前の時代では、言語の変化は数年または数十年にわたって発生していましたが、現在では数日または数時間で変化する可能性があります。

SF攻撃で91歳のアジア人女性が殴られ、コンクリートに叩きつけられた

犯罪擁護派のオークランドが暴力犯罪者のロミオ・ロレンゾ・パーハムを釈放

SF攻撃で91歳のアジア人女性が殴られ、コンクリートに叩きつけられた

認知症を患っている 91 歳のアジア人女性が最近、47 番街のアウター サンセット地区でロメオ ロレンゾ パーハムに襲われました。伝えられるところによると、被害者はサンフランシスコの通りを歩いていたところ、容疑者に近づき、攻撃を受け、暴行を受けました。

ℝ

“And a river went out of Eden to water the garden, and from thence it was parted and became into four heads” Genesis 2:10. ? The heart is located in the middle of the thoracic cavity, pointing eastward.

メリック・ガーランドはアメリカに失敗しましたか?

バイデン大統領の任期の半分以上です。メリック・ガーランドは何を待っていますか?

メリック・ガーランドはアメリカに失敗しましたか?

人々にチャンスを与えることは、人生で少し遅すぎると私は信じています。寛大に。

Language