メールアドレスの条件(RFC)って複雑すぎますね。
AIに一覧を作ってもらいました。
コピペできるようにメモを残します。
これでも網羅できてるのか、不安ですが一応メモとして残します。
No,分類,違反条件,RFC根拠,NG例,OK例,SQL検出条件,運用上の注意・誤検知リスク
1,構造,@ が存在しない,RFC 5322 §3.4.1,taro.example.com,taro@example.com,"LOCATE('@', v) = 0",確実に配送不能
2,構造,@ が2個以上,RFC 5322 §3.4.1,a@b@example.com,a@example.com,"CHAR_LENGTH(v) - CHAR_LENGTH(REPLACE(v,'@','')) > 1","""a@b""@example.com は正当なため誤検知の可能性"
3,構造,local部が空,RFC 5322 §3.4.1,@example.com,taro@example.com,"v LIKE '@%'",確実に配送不能
4,構造,domain部が空,RFC 5322 §3.4.1,taro@,taro@example.com,"v LIKE '%@'",確実に配送不能
5,local部,先頭がドット,RFC 5322 §3.4.1 dot-atom,.taro@example.com,taro@example.com,"local_part LIKE '.%'",旧キャリアメールで実在し配送可能な場合あり
6,local部,末尾がドット,RFC 5322 §3.4.1 dot-atom,taro.@docomo.ne.jp,taro@docomo.ne.jp,"local_part LIKE '%.'",docomo/au で実在・配送可能。除外推奨
7,local部,連続ドット,RFC 5322 §3.4.1 dot-atom,ta..ro@ezweb.ne.jp,ta.ro@ezweb.ne.jp,"local_part LIKE '%..%'",旧キャリアメールで実在。除外推奨
8,local部,atext以外の文字を含む,RFC 5322 §3.2.3,"ta(ro@example.com",taro@example.com,"local_part REGEXP '[^A-Za-z0-9!#$%&''*+/=?^_`{|}~.-]'",引用符付き形式は例外
9,local部,64オクテット超,RFC 5321 §4.5.3.1.1,65文字以上のlocal部,64オクテット以内,OCTET_LENGTH(local_part) > 64,MTAが拒否する
10,domain部,255オクテット超,RFC 5321 §4.5.3.1.2,256文字以上のドメイン,255オクテット以内,OCTET_LENGTH(domain_part) > 255,実データではほぼ発生しない
11,全体,254オクテット超,RFC 5321 §4.5.3.1.3,255文字以上のアドレス,254オクテット以内,OCTET_LENGTH(v) > 254,MTAが拒否する
12,domain部,ドットを含まない,RFC 5321 §2.3.5,taro@localhost,taro@example.com,"domain_part NOT LIKE '%.%'",FQDN必須。社内システム由来の値に注意
13,domain部,先頭または末尾がドット,RFC 1035 §2.3.1,taro@.example.com,taro@example.com,"domain_part LIKE '.%' OR domain_part LIKE '%.'",確実に名前解決不能
14,domain部,連続ドット,RFC 1035 §2.3.1,taro@example..com,taro@example.com,"domain_part LIKE '%..%'",確実に名前解決不能
15,domain部,ラベルがハイフンで開始または終了,RFC 1035 §2.3.1,taro@-example.com,taro@example.com,"domain_part LIKE '-%' OR domain_part LIKE '%-' OR domain_part LIKE '%.-%' OR domain_part LIKE '%-.%'",IDN変換前の値に注意
16,domain部,ラベルが63オクテット超,RFC 1035 §2.3.4,64文字以上のラベル,63オクテット以内,"domain_part REGEXP '(^|\\.)[^.]{64,}(\\.|$)'",実データではほぼ発生しない
17,domain部,TLDが数字のみ,RFC 5321 §4.1.2,taro@example.123,taro@example.com,"SUBSTRING_INDEX(domain_part,'.',-1) REGEXP '^[0-9]+$'",IPアドレス直書きの誤入力を検出
18,domain部,ハイフン以外の記号を含む,RFC 1035 §2.3.1,taro@my_host.example.com,taro@my-host.example.com,"domain_part REGEXP '[^A-Za-z0-9.-]'",アンダースコアの混入が多い
19,domain部,IPリテラルの角括弧が不正,RFC 5321 §4.1.3,taro@192.0.2.1,taro@[192.0.2.1],"domain_part REGEXP '^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$'",角括弧付きは正当なので除外対象
20,文字,非ASCII文字を含む,RFC 5321 §2.3.1 / RFC 6531,taro@example.com,taro@example.com,"OCTET_LENGTH(v) <> CHAR_LENGTH(v)",全角入力の混入が最多。SMTPUTF8非対応MTAでは配送不能
21,文字,空白文字を含む,RFC 5322 §3.2.3,ta ro@example.com,taro@example.com,"v REGEXP '[[:space:]]'","""ta ro""@example.com は正当"
22,文字,前後に空白がある,RFC 5322 §3.4.1,(末尾に半角空白),taro@example.com,"raw_mail <> TRIM(raw_mail)",TRIMで自動修正可能
23,文字,制御文字を含む,RFC 5322 §3.2.3,末尾に改行やタブ,taro@example.com,"v REGEXP '[[:cntrl:]]'",CSV取込時の混入が典型
24,書式,引用符が閉じていない,RFC 5322 §3.2.4,"""taro@example.com",taro@example.com,"(CHAR_LENGTH(v) - CHAR_LENGTH(REPLACE(v,'""',''))) % 2 = 1",実データでは稀
25,書式,括弧コメントが閉じていない,RFC 5322 §3.2.2,taro(comment@example.com,taro@example.com,"(v LIKE '%(%') <> (v LIKE '%)%')",実データでは稀
26,書式,カンマまたはセミコロンを含む,RFC 5322 §3.4,"a@example.com,b@example.com",a@example.com,"v REGEXP '[,;]'",複数アドレスが1カラムに連結された状態
27,書式,山括弧が残っている,RFC 5322 §3.4,<taro@example.com>,taro@example.com,"v LIKE '<%' OR v LIKE '%>'",display-name付き形式の取込ミス
28,書式,表示名が付いている,RFC 5322 §3.4,山田太郎 <taro@example.com>,taro@example.com,"v REGEXP '[[:space:]]<.+>$'",抽出して正規化可能
割と見かけるのが、「(..)ドットの連続がある。」とか「.@」になってるなど。
それ以外にもたくさんルールがあるのは把握してたんですが、覚えきれません…。
「RFC違反でもローカル部分を""(ダブルクォーテーション)で括れば送信可能になる」みたいな話もあったりして、余計にややこしいです。
参考:
https://datatracker.ietf.org/doc/html/rfc1035
https://datatracker.ietf.org/doc/html/rfc5321
https://datatracker.ietf.org/doc/html/rfc5322
https://datatracker.ietf.org/doc/html/rfc6531