コミュニティ

メールアドレスを表す現実的な正規表現

この記事は最終更新日から1年以上が経過しています。

RFC5322で定義されているメールアドレスの書式を完全にサポートすることは簡単ではありませんが、適当な正規表現を紹介してOKとする記事があとを絶ちません。

HTML5には input[type=email] という要素があり、メールアドレスの書式チェックをクライアントサイドで行えるようになっています。このチェックでは、下記の(Perl5の記法にならった)正規表現を使っています。

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

注釈に

この要件は電子メールの構文を定義するRFC5322に対して 意図的に違反 (willful violation) している。

とあるように、仕様を完全に満足する正規表現ではありませんので、電子メールヘッダを解析するような本格的な用途に対しては不十分ですが、WEBサービスに対するユーザー入力を検証する程度であれば、この正規表現を採用しておくのが無難ではないでしょうか。

そして、せめて + をlocal-partに含むメールアドレスを拒否するサービスがこの世から絶滅しますように。

sakuro
ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
コメント

404 Blog Not Found の管理人が嫌いなタイプの正規表現w

このレベルの正規表現でチェックするなら使わないか

正規表現
$target =~ m/[\x00-\x7f]+@[\x00-\x7f]+/g;

でチェックするのと同意かと
複雑見えて実は全然あってないというレベルなので

また

nos@[202.26.186.51]

というメールアドレスも有りなのだがそれをはじいてるというw

CRF5322#page-18

脊髄反射乙です:)

(編集済み)

Wikipediaに忠実に従い、@より前の部分のみ判定する正規表現書いてみました。
誤りがあれば教えてください。

ちなみに私は

  • バックスラッシュは全てPHP言語レベルでのエスケープも行う
  • 最大マッチは可能な限り独占的マッチに置き換える

というポリシーのもと書いてるので、違和感を覚える人もいるかもしれませんが、私はこちらの方が自然だと考えます。
前者に関しては、JavaやCなどの厳格な言語では逆にこうしないとその文字が認識されなかったり、 コンパイルエラー になります。
後者に関しては、無駄なバックトラックを行わないことで 実行速度の向上 が期待できます。

メールアドレス正規表現(前半)
<pre>
<?php

$dot_string = '(?:[A-Za-z0-9!#$%&*+=?^_`{|}~\'\\/-]|(?<!\\.|\\A)\\.(?!\\.|@))';
$quoted_string = '(?:\\\\\\\\|\\\\"|\\\\?[A-Za-z0-9!#$%&*+=?^_`{|}~()<>[\\]:;@,. \'\\/-])';

$pattern = "/\\A(?:{$dot_string}++|\"{$quoted_string}++\")@example\\.com\\z/";

var_dump(

    '有効なアドレス',
    preg_match($pattern, 'Abc@example.com'),
    preg_match($pattern, 'Abc.123@example.com'),
    preg_match($pattern, 'user+mailbox/department=shipping@example.com'),
    preg_match($pattern, '!#$%&\'*+-/=?^_`.{|}~@example.com'),
    preg_match($pattern, '"Abc@def"@example.com'),
    preg_match($pattern, '"Fred\\ Bloggs"@example.com'),
    preg_match($pattern, '"Joe.\\\\Blow"@example.com'),
    preg_match($pattern, '".dot_kara_hazimaru"@example.com'),
    preg_match($pattern, '"I.likeyou."@example.com'),
    preg_match($pattern, '"I..love...you"@example.com'),

    '無効なアドレス',
    preg_match($pattern, 'Abc.@example.com'),
    preg_match($pattern, 'Abc..123@example.com'),
    preg_match($pattern, '.dot_kara_hazimaru@example.com'),
    preg_match($pattern, 'I.like.you.@example.com'),
    preg_match($pattern, 'I..love...you@example.com')

);
?>
</pre>

誰か@より後ろの部分も判定するやつ作ってください(丸投げ)

@mpyw うちのコメント熟読よろし

HTML5 の "willful violation" というのは、「元々の仕様がカスだから現実的な仕様を HTML5 で再定義する」っていう意味なので、本格的な用途でこそこれを使っておいた方がへたに自分で考えるよりも無難ですよ

あなたもコメントしてみませんか :)
すでにアカウントを持っている方は
ユーザーは見つかりませんでした