メールアドレスのフォーマットチェックのリンク集

メールアドレスのフォーマットチェックは調べれば調べるほど「正しいメールアドレス」って何？究極なんでもいけんじゃね？と諦めたいですが、そのシステムの運用や使い方に適合すればいいんだと思います。毎回悩むのが面倒くさいので、いろいろな種類を集めておきます。

# 超ふわっと
```text:@があればいける
^(.+)@(.+)$
```

- [jQueryでフォーム入力をチェックする ｜ Tips Note by TAM](https://www.tam-tam.co.jp/tipsnote/javascript/post3828.html)

# それなりに
```text:"とかIPアドレスとか無理だけどよく見るメアドはいける
^[\w.!#$%&'*+\/=?^_`{|}~-]+@[\w-]+(?:\.[\w-]+)*$
^(?:[\w!#$%&'*+\/\-=?^`{|}~]+(?:\.[\w!#$%&'*+\/\-=?^`{|}~]+)*)@(?:[a-zA-Z]+[a-zA-Z0-9-]*[a-zA-Z0-9](?:\.[a-zA-Z]+[a-zA-Z0-9-]*[a-zA-Z0-9])*(?:\.[a-zA-Z0-9]+))$
```

- [メールアドレスを表す現実的な正規表現 - Qiita](https://qiita.com/sakuro/items/1eaa307609ceaaf51123)
- [正規表現：メールアドレスかどうか調べる - phpspot](http://phpspot.net/php/pg%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE%EF%BC%9A%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%8B%E3%81%A9%E3%81%86%E3%81%8B%E8%AA%BF%E3%81%B9%E3%82%8B.html)

# RFC822

- [英語のRFC822(Standard for the Format of Arpa Internet Text Messages)](https://www.w3.org/Protocols/rfc822/)
- [日本語のRFC822](http://jbpe.tripod.com/rfcj/rfc-822.j.sjis.txt)
- [日本語のRFC2822(Internet Message Format)](http://srgia.com/docs/rfc2822j.html)
- [RFC 822 と RFC 2822 - あどけない話](https://kazu-yamamoto.hatenablog.jp/entry/20080107/1199679405)
- [RFC822の正規表現(長い・・)](http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html)

```ini:RFC822
address = mailbox                                           ; one addressee
          ;または
          phrase ":" [#mailbox] ";"                         ; named list

mailbox = local-part "@" domain                             ; simple address
          ;または
          phrase "<" [route] local-part "@" domain ">"      ; name & addr-spec

route       =  1#("@" domain) ":"                           ; path-relative
local-part  =  word *("." word)                             ; uninterpreted 大文字小文字を区別しない
domain      =  sub-domain *("." sub-domain)
sub-domain = 1*<any CHAR except(除外する) specials, SPACE and CTLs>
             ; または
             domain-literal
domain-literal = "[" *(dtext / quoted-pair) "]"             ; DOMAIN-LITERALSの使用はあまり薦められません。
dtext = <any CHAR excluding(除く) "[",                        ; => may be folded
        "]", "\" & CR, & including(を含む) linear-white-space>

addr-spec   =  local-part "@" domain                        ; global address
domain-ref = 1*<any CHAR except(除外する) specials, SPACE and CTLs>
group = phrase ":" [#mailbox] ";"
quoted-pair = "\" CHAR                                      ; 任意の文字を引用できます
route-addr = "<" [route] addr-spec ">"
specials =  ()<>@,;:\".[] ; 単語内で使用するには、quoted-stringで囲まれた文字列でなければなりません。
```

# 「RFC5321」「RFC5322」準拠
```text:RFC5321とRFC5322で違反(ローカル部を「"」で囲むとOK)
# 先頭に「.」がある
.localPart@domain.co.jp
# 「@」の直前に「.」がある
localPart.@domain.co.jp
# ローカル部に「.」が連続している
localPart..@domain.co.jp
local..Part@domain.co.jp
# 半角英数字と「.!#$%&‘*+–/=?^_{|}~」以外を使っている
local[Part@domain.co.jp
local@Part@domain.co.jp
```

携帯電話のアドレスは準拠していないことがあります = 実際にはあるけど弾くかもね

- [日本語のRFC5321(Simple Mail Transfer Protocol)](http://srgia.com/docs/rfc5321j.html#p4.5.3.1.1)
- [日本語のRFC5322(Internet Message Format)](http://srgia.com/docs/rfc5322j.html)
- [【Java初心者向け】メールアドレスの正規表現の書き方まとめ](https://eng-entrance.com/programming-reg-mail)

### 「..@」はだめ？「"」でローカル部を囲んだらOKにする？ドメインはIPアドレスOK?コメントはNG?

- [NTTドコモ、メールアドレスのルールを変更 〜 ピリオド連続などが使用不可に | RBB TODAY](https://www.rbbtoday.com/article/2009/04/03/59059.html)
- [RFCに準拠したメールアドレスの正規表現](http://www.din.or.jp/~ohzaki/mail_regex.htm)

# ドメイン部分
> ICANNは、ドット無しを前提としたトップレベルドメインの登録は現時点で認めていない。例えば、Googleが申請した search というドット無しトップレベルドメインの申請は棄却した。
> [ドット無しトップレベルドメイン](https://www.wdic.org/w/WDIC/%E3%83%89%E3%83%83%E3%83%88%E7%84%A1%E3%81%97%E3%83%88%E3%83%83%E3%83%97%E3%83%AC%E3%83%99%E3%83%AB%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3)


- [日本語のRFC1034(ドメイン部分)](http://srgia.com/docs/rfc1034j.html#p3.4)
- 「ドメインが正しい=テスト用じゃない」と考える場合は`example.com` `example.net` `example.org`はテスト用なので正しくなくなる
    - [test.comやaaa.comをテストデータに使うのはやめましょうという話 - blog.ko31.com](https://blog.ko31.com/201304/sample-domain-example/#co-index-5)

```ini:RFC1034
<domain> ::= <subdomain> | " " ;ドメイン名には大文字も小文字も許されるが、それには重要な違いがないことに注意してほしい。つまり、同じつづりで大文字・小文字の異なる二つの名前は同じ物として扱われるということである。
<subdomain> ::= <label> | <subdomain> "." <label>
<label> ::= <letter> [ [ <ldh-str> ] <let-dig> ] ;ラベルは ARPANET のホスト名の規則にしたがわなければならない。ラベルは文字で始まり、文字または数字で終わり、間には文字・数字・ハイフンだけが含まれなければならない。ラベルの長さにも制約があり、63 文字以下でなければならない。
<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
<let-dig-hyp> ::= <let-dig> | "-"
<let-dig> ::= <letter> | <digit>
<letter> ::= 大文字の A から Z と小文字の a から z の、アルファベット52 文字の内の任意の一文字
<digit> ::= 0 から 9 までの 10 個の数字の内の任意の一文字
```

## ドメイン部分にIPアドレスを書くときの決まり
```ini:RFC5321
IPv4-address-literal  = Snum 3("."  Snum)
IPv6-address-literal  = "IPv6:" IPv6-addr
General-address-literal  = Standardized-tag ":" 1*dcontent
Standardized-tag  = Ldh-str
                  ; Standardized-tag はスタンダードトラック RFC に                  ; おいて規定され、IANA に登録されなければならない
                  ; (MUST)

dcontent       = %d33-90 / ; Printable US-ASCII
               %d94-126 ; excl. "[", "\", "]"

Snum           = 1*3DIGIT ; 0 ～ 255 までの 10 進整数値を表す
IPv6-addr      = IPv6-full / IPv6-comp / IPv6v4-full / IPv6v4-comp
IPv6-hex       = 1*4HEXDIG ;HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"小文字の "a", "b", "c", "d", "e", "f"もOKなので[1-9a-fA-F]的な感じ by RFC2234のCore Rules
IPv6-full      = IPv6-hex 7(":" IPv6-hex)
IPv6-comp      = [IPv6-hex *5(":" IPv6-hex)] "::"
               [IPv6-hex *5(":" IPv6-hex)] ; "::" は、値ゼロの 16 ビットグループが少なくとも2 つあることを表す。"::" に加えて高々 6 グループが現れる可能性がある。
;IPv4 マップ式 IPv6 アドレス------------------------------------------------------------
IPv6v4-full    = IPv6-hex 5(":" IPv6-hex) ":" IPv4-address-literal
IPv6v4-comp    = [IPv6-hex *3(":" IPv6-hex)] "::"
               [IPv6-hex *3(":" IPv6-hex) ":"]
               IPv4-address-literal ; "::" は、値ゼロの 16 ビットグループが少なくとも2 つあることを表す。"::" と IPv4-address-literalとに加えて高々 4 グループが現れる可能性がある。
```

- [IPv6のフォーマット - IBM Knowledge Center](https://www.ibm.com/support/knowledgecenter/ja/ssw_ibm_i_71/rzai2/rzai2ipv6addrformat.htm)
- [RFC2234のCore Rules](https://www.ietf.org/rfc/rfc2234.txt)


# 正規表現がわからなすぎるときは誰かに頼ってみる
- [正規表現がわからないから見たいリンク集 - Qiita](https://qiita.com/ponsuke0531/items/64f6a180a4b699336096)
- [HTML5ならRFC完全準拠じゃないけど<input type="email">に頼ってみる](https://developer.mozilla.org/ja/docs/Web/HTML/Element/Input/email)
- [Javaなら「RFC822」だけどInternetAddressに頼ってみる](https://docs.oracle.com/javaee/7/api/index.html?javax/mail/internet/InternetAddress.html)
    - [Class HeaderTokenizer](https://docs.oracle.com/javaee/7/api/javax/mail/internet/HeaderTokenizer.html)
    - [Class MimeMessage](https://docs.oracle.com/javaee/7/api/javax/mail/internet/MimeMessage.html)
    - [ApacheさんのClass EmailValidator](https://commons.apache.org/proper/commons-validator/apidocs/org/apache/commons/validator/routines/EmailValidator.html)
- [PHPなら「RFC822」だけどmailparse_rfc822_parse_addressesに頼ってみる](http://php.net/manual/ja/function.mailparse-rfc822-parse-addresses.php)
- [C#ならMailAddressに頼ってみる](https://docs.microsoft.com/ja-jp/dotnet/api/system.net.mail.mailaddress?view=netframework-4.7.2)


# 入力チェック以外も気にしておく
入力チェックができても他のところでハジケルこともあります。

- メールアドレスをCSV出力することがある？「,」「"」は気になるところ
- DBのカラムサイズに合っている？
- メールを送信する処理で何を使うかによって入力チェックOKでも送信できないこともあります。
    - [perl Mail::Sendmail はRFC違反の携帯メールアドレスに送信出来ない](http://perl.no-tubo.net/2011/03/08/perl-mailsendmail-%E3%81%AFrfc%E9%81%95%E5%8F%8D%E3%81%AE%E6%90%BA%E5%B8%AF%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AB%E9%80%81%E4%BF%A1%E5%87%BA%E6%9D%A5%E3%81%AA/)

# メールアドレスのフォーマットを考えるときに参考にしたいサイト
- [RFC違反メールアドレスを知っていますか？ : ビジネスとIT活用に役立つ情報](https://www.asobou.co.jp/blog/web/mail-rfc)
- [結局 &quot;メールアドレスの規格&quot; ってどこ？ - Qiita](https://qiita.com/wingsys/items/5c00f5ff2e34a6b7ee10)
- [ 「メールアドレスのルール」なんて使ってはいけない3つの理由 - めもおきば](https://d.nekoruri.jp/entry/20131127/1385521425)
- [入力バリデーションはセキュリティ対策として＊あてにする＊ものではありません &#8211; yohgaki&#039;s blog](https://blog.ohgaki.net/input-validation-is-not-dependable-but-efficient-security-measure)
- [正規表現によるメールアドレスチェックの正解がわからないので、自己責任で。 | doli blog](http://blog.doli.jp/blog/2014/post780/)
- [正しいメールアドレスを入力させるのは至難](https://w3g.jp/blog/put_correct_email)

# 正規表現が長いのでチェック
- [(Js)正規表現が図でみれるRegulex](https://jex.im/regulex/#!flags=&re=)
- [(PHP)正規表現デバッグツール](http://landhere.jp/services/etc/preg_test.php)
- [正規表現チェッカー | WEB ARCH LABO](https://weblabo.oscasierra.net/tools/regex/)
- [regex101: build, test, and debug regex]()
- [Online regex tester and debugger: PHP, PCRE, Python, Golang and JavaScript](https://regex101.com/)
- [(Js/PHP)正規表現チェッカー PHP: preg_match() / JavaScript: match()](http://okumocchi.jp/php/re.php)