がるの健忘録

エンジニアでゲーマーで講師で占い師なおいちゃんのブログです。

メールアドレスの確認(余談? 本題? ググったコードの実検証)

実コードです。
後で修正いれる可能性があるんで、気づいた事とかあったら突っ込んでくださいませ。

<?php

// 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
function phpspot($text) {
  if (preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/", $text)) {
    return true;
  } else {
    return false;
  }
}
// http://www.ideaxidea.com/archives/2009/03/practical_php_regexs.html
function idea($email) {
  if (preg_match('/^[^0-9][a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)*[@][a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)*[.][a-zA-Z]{2,4}$/',$email)) {
    return true;
  } else {
    return false;
  }
}

//http://qiita.com/tabo_purify/items/aa279cd28abdeba0873c
function tabo_purify($mail) {
  if (preg_match('|^[0-9a-z_./?-]+@([0-9a-z-]+\.)+[0-9a-z-]+$|', $mail)) {
    return true;
  }else{
    return false;
  }
}
function doli($email) {
  if ( preg_match('/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/i', $email) ){
    return true;
  } else {
    return false;
  }
}

// http://www.seesaa.hitsug.net/article/406595659.html
function seesaa($email){
  if(preg_match('/^[a-zA-Z0-9_.!~*\'();\/?:\&=+\$,%#-]+@[A-Za-z0-9_.-]+\.[A-Za-z0-9]+$/', $email)){
    return true;
  } else {
    return false;
  }
}

// http://d.hatena.ne.jp/yachin29/20130410/p1
function yachin29($email){
  if (preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/", $email)) {
    return true;
  } else {
    return false;
  }
}

// http://doremi.s206.xrea.com/php/tips/preg.html
function doremi_1($email) {
  if (preg_match('/^[\w\-\.]+@[\w\-\.]+$/D', $email)) {
    return true;
  }
  //else
  return false;
}
function doremi_2($email) {
  if (preg_match('/^\w+(?:[\.\-]\w+)*@\w+(?:-\w+)?(?:\.\w+(?:-\w+)?)+$/D', $email)) {
    return true;
  }
  //else
  return false;
}

// http://qiita.com/mpyw/items/257eabe0b43b1e02e6f7
function mpyw($email, $strict = true) {
    $dot_string = $strict ?
        '(?:[A-Za-z0-9!#$%&*+=?^_`{|}~\'\\/-]|(?<!\\.|\\A)\\.(?!\\.|@))' :
        '(?:[A-Za-z0-9!#$%&*+=?^_`{|}~\'\\/.-])'
    ;
    $quoted_string = '(?:\\\\\\\\|\\\\"|\\\\?[A-Za-z0-9!#$%&*+=?^_`{|}~()<>[\\]:;@,. \'\\/-])';
    $ipv4_part = '(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
    $ipv6_part = '(?:[A-fa-f0-9]{1,4})';
    $fqdn_part = '(?:[A-Za-z](?:[A-Za-z0-9-]{0,61}?[A-Za-z0-9])?)';
    $ipv4 = "(?:(?:{$ipv4_part}\\.){3}{$ipv4_part})";
    $ipv6 = '(?:' .
        "(?:(?:{$ipv6_part}:){7}(?:{$ipv6_part}|:))" . '|' .
        "(?:(?:{$ipv6_part}:){6}(?::{$ipv6_part}|:{$ipv4}|:))" . '|' .
        "(?:(?:{$ipv6_part}:){5}(?:(?::{$ipv6_part}){1,2}|:{$ipv4}|:))" . '|' .
        "(?:(?:{$ipv6_part}:){4}(?:(?::{$ipv6_part}){1,3}|(?::{$ipv6_part})?:{$ipv4}|:))" . '|' .
        "(?:(?:{$ipv6_part}:){3}(?:(?::{$ipv6_part}){1,4}|(?::{$ipv6_part}){0,2}:{$ipv4}|:))" . '|' .
        "(?:(?:{$ipv6_part}:){2}(?:(?::{$ipv6_part}){1,5}|(?::{$ipv6_part}){0,3}:{$ipv4}|:))" . '|' .
        "(?:(?:{$ipv6_part}:){1}(?:(?::{$ipv6_part}){1,6}|(?::{$ipv6_part}){0,4}:{$ipv4}|:))" . '|' .
        "(?::(?:(?::{$ipv6_part}){1,7}|(?::{$ipv6_part}){0,5}:{$ipv4}|:))" . 
    ')';
    $fqdn = "(?:(?:{$fqdn_part}\\.)+?{$fqdn_part})";
    $local = "({$dot_string}++|(\"){$quoted_string}++\")";
    $domain = "({$fqdn}|\\[{$ipv4}]|\\[{$ipv6}]|\\[{$fqdn}])";
    $pattern = "/\\A{$local}@{$domain}\\z/";
    return preg_match($pattern, $email, $matches) &&
        (
            !empty($matches[2]) && !isset($matches[1][66]) && !isset($matches[0][256]) ||
            !isset($matches[1][64]) && !isset($matches[0][254])
        )
    ;
}

// http://fdays.blogspot.jp/2007/10/rfc-2822-j0hn-d0e-10-pregmatch-9.html
function fdays_1($m) {
  //local part
  $atext = "[-!#-'*+/-9=?^-~]";
  $atom = $atext . '+';
  $dot_atom = $atom . '(//.' . $atom . ')*'; //2

  $qtext = '[]-~!#-[]';
  $text = '[ -~]';
  $quoted_pair = '////' . $text; //4
  $quoted_string = '"(' . $qtext . '|' . $quoted_pair . ')*"'; //3

  $local_part = '(' . $dot_atom . '|' . $quoted_string . ')';

  //domain
  $label = '[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?'; //7, 8
  $domain = $label . '(//.' . $label . ')*//.([a-z]{2,4}|museum)'; //6

  //全体
  $addr_spec = $local_part . '@' . $domain; //1

  $regexp = '/^' . str_replace('/', '\\/', $addr_spec) . '$/i';

  if (preg_match($regexp, $m)) {
    return true;
  }
  //else
  return false;
}
function fdays_2($value) {
  if (preg_match('/^[-+\\w]+(\\.[-+\\w]+)*@[-a-z0-9]+(\\.[-a-z0-9]+)*\\.[a-z]{2,6}$/i', $value)) {
    return true;
  }
  //else
  return false;
}
function fdays_3($value) {
  if (preg_match('/^[-+.\\w]+@[-a-z0-9]+(\\.[-a-z0-9]+)*\\.[a-z]{2,6}$/i', $value)) {
    return true;
  }
  //else
  return false;
}


// ---------------------------------------------

// http://catbot.net/blog/2007/06/re_php.html
// ソースは PEARから直接( http://download.pear.php.net/package/Mail-1.3.0.tgz )
function pear($data, $strict = false)
{
    $regex = $strict ? '/^([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})$/i' : '/^([*+!.&#$|\'\\%\/0-9a-z^_`{}=?~:-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})$/i';
    if (preg_match($regex, trim($data), $matches)) {
        //return array($matches[1], $matches[2]);
        return true;
    } else {
        return false;
    }
}


// http://catbot.net/blog/2007/06/re_php.html


// 多分こういう関数だと思う
define('VALID_EMAIL', '/\\A(?:^([a-z0-9][a-z0-9_\\-\\.\\+]*)@([a-z0-9][a-z0-9\\.\\-]{0,63}\\.(com|org|net|biz|info|name|net|pro|aero|coop|museum|[a-z]{2,4}))$)\\z/i');
function cake($s) {
    if (preg_match(VALID_EMAIL, $s, $matches)) {
        //return array($matches[1], $matches[2]);
        return true;
    } else {
        return false;
    }

}
//
function Ethna($mailaddress)
{
    if (preg_match('/^([a-z0-9_]|\-|\.|\+)+@(([a-z0-9_]|\-)+\.)+[a-z]{2,6}$/i', $mailaddress)) {
        return true;
    }
    return false;
}
// XXX 第二引数は省略
// XXX classメソッドぽいので、$thisをcallするあたり省略
// ドメインチェックは(今回の趣旨から外れるし)省略
function symfony_1(&$value /*, &$error*/) {
  return _symfony($value, false);
}
function symfony_2(&$value /*, &$error*/) {
  return _symfony($value, true);
}
function _symfony(&$value, $strict)
{
  $error; // XXX
  //$strict = $this->getParameterHolder()->get('strict');
  if ($strict == true)
  {
    $re = '/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i';
  }
  else
  {
    /* Cal Henderson: http://iamcal.com/publish/articles/php/parsing_email/pdf/
     * The long regular expression below is made by the following code
     * fragment:
     *
     *   $qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]';
     *   $dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]';
     *   $atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c'
     *         . '\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+';
     *   $quoted_pair = '\\x5c\\x00-\\x7f';
     *   $domain_literal = "\\x5b($dtext|$quoted_pair)*\\x5d";
     *   $quoted_string = "\\x22($qtext|$quoted_pair)*\\x22";
     *   $domain_ref = $atom;
     *   $sub_domain = "($domain_ref|$domain_literal)";
     *   $word = "($atom|$quoted_string)";
     *   $domain = "$sub_domain(\\x2e$sub_domain)*";
     *   $local_part = "$word(\\x2e$word)*";
     *   $addr_spec = "$local_part\\x40$domain";
     */

    $re = '/^([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-'
         .'\\x5d\\x7f-\\xff]+|\\x22([^\\x0d\\x22\\x5c\\x80-\\xff]|\\x5c\\x00-'
         .'\\x7f)*\\x22)(\\x2e([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-'
         .'\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x22([^\\x0d\\x22\\x5c\\x80'
         .'-\\xff]|\\x5c\\x00-\\x7f)*\\x22))*\\x40([^\\x00-\\x20\\x22\\x28\\x29'
         .'\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x5b([^'
       .'\\x0d\\x5b-\\x5d\\x80-\\xff]|\\x5c\\x00-\\x7f)*\\x5d)(\\x2e([^\\x00-'
         .'\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-'
         .'\\xff]+|\\x5b([^\\x0d\\x5b-\\x5d\\x80-\\xff]|\\x5c\\x00-\\x7f)*'
         .'\\x5d))*$/'
    ;
  }

  if (!preg_match($re, $value))
  {
    //$error = $this->getParameterHolder()->get('email_error');
    return false;
  }

/*
  $checkDomain = $this->getParameterHolder()->get('check_domain');
  if ($checkDomain && function_exists('checkdnsrr'))
  {
    $tokens = explode('@', $value);
    if (!checkdnsrr($tokens[1], 'MX') && !checkdnsrr($tokens[1], 'A'))
    {
      $error = $this->getParameterHolder()->get('email_error');

      return false;
    }
  }
*/
  return true;
} 

// PHP
function php_filter($email) {
  $r = filter_var($email, FILTER_VALIDATE_EMAIL);
  if (false === $r) {
    return false;
  }
  // else
  return true;
}

/*
// 未テストだけど本来的にvalid
// 「お名前 <アドレス>」は、うち(MagicWeapon)には「引っぺがすメソッド」あるから一旦無視
<foo@example.com>
foo <foo@example.com>
// 「ドメインpartにIPアドレス指定」は今回の趣旨から外れるから無視
canada@[192.168.0.1]
*/

// 本来invalid
$invalid = [
  'dameexample.com' => '@がない',
  '.da.me@example.com' => 'local-part先頭の.(ドット)はNG',
  'da.me.@example.com' => 'local-part最後の.(ドット)はNG',
  'da..me@example.com' => '連続した.(ドット)はNG',
  'da.me@.example.com' => 'domain-part先頭の.(ドット)はNG',
  'da.me@example.com_' => 'domain-partの最後はアルファベットまたは数字のみ',
  'da.me@example.com.' => 'domain-partの最後はアルファベットまたは数字のみ(その2)',
  'nobody@add_example.com' => 'domain-partのアンダースコアはNG',
];

// 本来valid
$valid = [
  'nobody@example.com' => '普通のアドレス',
  '0nobody@example.com' => '先頭を数字に',
  '!nobody@example.com' => '先頭を記号に',
  'nobody@1st.example.com' => 'ドメイン名の先頭を数字に(昔は駄目だった)',
  'Abc\@def@example.com' => 'quoted pair(ただしこれはobsolete)',
  "!#$%&'*+-/=?^_`.{|}~@example.com" => '使用可能な記号の群れ',
  '"da.me.."@example.com' => 'これは「quoted string」なのでvalidなパターンその1',
  '"nobody@nobody"@example.com' => 'これは「quoted string」なのでvalidなパターンその2',
  'nobody+regexp@gmail.com' => 'いわゆる拡張アドレスその1',
  'nobody-regexp@gmail.com' => 'いわゆる拡張アドレスその2',
  '"nobody+regexp"@gmail.com' => 'いわゆる拡張アドレスその3(拡張+quoted)',
  '"nobody-regexp"@gmail.com' => 'いわゆる拡張アドレスその4(拡張+quoted)',
];

$funcs = [
  'phpspot',
  'idea',
  'tabo_purify',
  'doli',
  'seesaa',
  'yachin29',
  'doremi_1',
  'doremi_2',
  'mpyw',
  // 'fdays_1', valid系が全部エラーになるので、一旦未使用にする
  'fdays_2',
  'fdays_3',
  'pear',
  'cake',
  'Ethna',
  'symfony_1',
  'symfony_2',
  'php_filter',
];

// ぶん回し: メールアドレス単位での「各処理」の具合
foreach(['invalid' => false, 'valid' => true] as $data => $expected_ret) {
echo "{$data}\n";
  foreach($$data as $email => $comment) {
    echo "  {$email} ({$comment})\n";
    foreach ($funcs as $func) {
      printf("    call %-15s:", $func);
      $r = $func($email);
      if ($r === $expected_ret) {
        echo "... OK!!\n";
      } else {
        echo "... NG orz\n";
      }
    }
    echo "\n";
  }
  echo "\n\n";
}

// ぶん回し:各処理単位での、メアドの具合
// ついでにカウント
$count = [];
foreach ($funcs as $func) {
  $count[$func] = ['OK' => 0, 'NG' => 0];
  printf("call %-15s\n", $func);
  foreach(['invalid' => false, 'valid' => true] as $data => $expected_ret) {
    echo "  {$data}\n";
    foreach($$data as $email => $comment) {
      //printf("    %-30s", $email);
      $r = $func($email);
      if ($r === $expected_ret) {
        //echo "... OK!!\n";
        $count[$func]['OK'] ++;
      } else {
        printf("    %-30s... NG orz(%s)\n", $email, $comment);
        //echo "... NG orz({$comment})\n";
        $count[$func]['NG'] ++;
      }
    }
  }
  echo "\n";
}

//
foreach($count as $func => $types) {
  echo "{$func}\n";
  foreach($types as $type => $i) {
    printf("    %s => %d\n", $type, $i);
  }
}


結果


invalid
 dameexample.com (@がない)
  call phpspot    :... OK!!
  call idea      :... OK!!
  call tabo_purify  :... OK!!
  call doli      :... OK!!
  call seesaa     :... OK!!
  call yachin29    :... OK!!
  call doremi_1    :... OK!!
  call doremi_2    :... OK!!
  call mpyw      :... OK!!
  call fdays_2    :... OK!!
  call fdays_3    :... OK!!
  call pear      :... OK!!
  call cake      :... OK!!
  call Ethna     :... OK!!
  call symfony_1   :... OK!!
  call symfony_2   :... OK!!
  call php_filter   :... OK!!

 .da.me@example.com (local-part先頭の.(ドット)はNG)
  call phpspot    :... OK!!
  call idea      :... NG orz
  call tabo_purify  :... NG orz
  call doli      :... OK!!
  call seesaa     :... NG orz
  call yachin29    :... OK!!
  call doremi_1    :... NG orz
  call doremi_2    :... OK!!
  call mpyw      :... OK!!
  call fdays_2    :... OK!!
  call fdays_3    :... NG orz
  call pear      :... NG orz
  call cake      :... OK!!
  call Ethna     :... NG orz
  call symfony_1   :... OK!!
  call symfony_2   :... NG orz
  call php_filter   :... OK!!

 da.me.@example.com (local-part最後の.(ドット)はNG)
  call phpspot    :... NG orz
  call idea      :... OK!!
  call tabo_purify  :... NG orz
  call doli      :... OK!!
  call seesaa     :... NG orz
  call yachin29    :... NG orz
  call doremi_1    :... NG orz
  call doremi_2    :... OK!!
  call mpyw      :... OK!!
  call fdays_2    :... OK!!
  call fdays_3    :... NG orz
  call pear      :... NG orz
  call cake      :... NG orz
  call Ethna     :... NG orz
  call symfony_1   :... OK!!
  call symfony_2   :... NG orz
  call php_filter   :... OK!!

 da..me@example.com (連続した.(ドット)はNG)
  call phpspot    :... NG orz
  call idea      :... OK!!
  call tabo_purify  :... NG orz
  call doli      :... OK!!
  call seesaa     :... NG orz
  call yachin29    :... NG orz
  call doremi_1    :... NG orz
  call doremi_2    :... OK!!
  call mpyw      :... OK!!
  call fdays_2    :... OK!!
  call fdays_3    :... NG orz
  call pear      :... NG orz
  call cake      :... NG orz
  call Ethna     :... NG orz
  call symfony_1   :... OK!!
  call symfony_2   :... NG orz
  call php_filter   :... OK!!

 da.me@.example.com (domain-part先頭の.(ドット)はNG)
  call phpspot    :... OK!!
  call idea      :... OK!!
  call tabo_purify  :... OK!!
  call doli      :... OK!!
  call seesaa     :... NG orz
  call yachin29    :... OK!!
  call doremi_1    :... NG orz
  call doremi_2    :... OK!!
  call mpyw      :... OK!!
  call fdays_2    :... OK!!
  call fdays_3    :... OK!!
  call pear      :... OK!!
  call cake      :... OK!!
  call Ethna     :... OK!!
  call symfony_1   :... OK!!
  call symfony_2   :... OK!!
  call php_filter   :... OK!!

 da.me@example.com_ (domain-partの最後はアルファベットまたは数字のみ)
  call phpspot    :... NG orz
  call idea      :... OK!!
  call tabo_purify  :... OK!!
  call doli      :... OK!!
  call seesaa     :... OK!!
  call yachin29    :... NG orz
  call doremi_1    :... NG orz
  call doremi_2    :... NG orz
  call mpyw      :... OK!!
  call fdays_2    :... OK!!
  call fdays_3    :... OK!!
  call pear      :... OK!!
  call cake      :... OK!!
  call Ethna     :... OK!!
  call symfony_1   :... NG orz
  call symfony_2   :... OK!!
  call php_filter   :... OK!!

 da.me@example.com. (domain-partの最後はアルファベットまたは数字のみ(その2))
  call phpspot    :... NG orz
  call idea      :... OK!!
  call tabo_purify  :... OK!!
  call doli      :... OK!!
  call seesaa     :... OK!!
  call yachin29    :... NG orz
  call doremi_1    :... NG orz
  call doremi_2    :... OK!!
  call mpyw      :... OK!!
  call fdays_2    :... OK!!
  call fdays_3    :... OK!!
  call pear      :... OK!!
  call cake      :... OK!!
  call Ethna     :... OK!!
  call symfony_1   :... OK!!
  call symfony_2   :... OK!!
  call php_filter   :... OK!!

 nobody@add_example.com (domain-partのアンダースコアはNG)
  call phpspot    :... NG orz
  call idea      :... NG orz
  call tabo_purify  :... OK!!
  call doli      :... OK!!
  call seesaa     :... NG orz
  call yachin29    :... NG orz
  call doremi_1    :... NG orz
  call doremi_2    :... NG orz
  call mpyw      :... OK!!
  call fdays_2    :... OK!!
  call fdays_3    :... OK!!
  call pear      :... OK!!
  call cake      :... OK!!
  call Ethna     :... NG orz
  call symfony_1   :... NG orz
  call symfony_2   :... OK!!
  call php_filter   :... OK!!



valid
 nobody@example.com (普通のアドレス)
  call phpspot    :... OK!!
  call idea      :... OK!!
  call tabo_purify  :... OK!!
  call doli      :... OK!!
  call seesaa     :... OK!!
  call yachin29    :... OK!!
  call doremi_1    :... OK!!
  call doremi_2    :... OK!!
  call mpyw      :... OK!!
  call fdays_2    :... OK!!
  call fdays_3    :... OK!!
  call pear      :... OK!!
  call cake      :... OK!!
  call Ethna     :... OK!!
  call symfony_1   :... OK!!
  call symfony_2   :... OK!!
  call php_filter   :... OK!!

 0nobody@example.com (先頭を数字に)
  call phpspot    :... OK!!
  call idea      :... NG orz
  call tabo_purify  :... OK!!
  call doli      :... OK!!
  call seesaa     :... OK!!
  call yachin29    :... OK!!
  call doremi_1    :... OK!!
  call doremi_2    :... OK!!
  call mpyw      :... OK!!
  call fdays_2    :... OK!!
  call fdays_3    :... OK!!
  call pear      :... OK!!
  call cake      :... OK!!
  call Ethna     :... OK!!
  call symfony_1   :... OK!!
  call symfony_2   :... OK!!
  call php_filter   :... OK!!

 !nobody@example.com (先頭を記号に)
  call phpspot    :... NG orz
  call idea      :... OK!!
  call tabo_purify  :... NG orz
  call doli      :... NG orz
  call seesaa     :... OK!!
  call yachin29    :... NG orz
  call doremi_1    :... NG orz
  call doremi_2    :... NG orz
  call mpyw      :... OK!!
  call fdays_2    :... NG orz
  call fdays_3    :... NG orz
  call pear      :... OK!!
  call cake      :... NG orz
  call Ethna     :... NG orz
  call symfony_1   :... OK!!
  call symfony_2   :... OK!!
  call php_filter   :... OK!!

 nobody@1st.example.com (ドメイン名の先頭を数字に(昔は駄目だった))
  call phpspot    :... OK!!
  call idea      :... OK!!
  call tabo_purify  :... OK!!
  call doli      :... OK!!
  call seesaa     :... OK!!
  call yachin29    :... OK!!
  call doremi_1    :... OK!!
  call doremi_2    :... OK!!
  call mpyw      :... NG orz
  call fdays_2    :... OK!!
  call fdays_3    :... OK!!
  call pear      :... OK!!
  call cake      :... OK!!
  call Ethna     :... OK!!
  call symfony_1   :... OK!!
  call symfony_2   :... OK!!
  call php_filter   :... OK!!

 Abc\@def@example.com (quoted pair(ただしこれはobsolete))
  call phpspot    :... NG orz
  call idea      :... NG orz
  call tabo_purify  :... NG orz
  call doli      :... NG orz
  call seesaa     :... NG orz
  call yachin29    :... NG orz
  call doremi_1    :... NG orz
  call doremi_2    :... NG orz
  call mpyw      :... NG orz
  call fdays_2    :... NG orz
  call fdays_3    :... NG orz
  call pear      :... NG orz
  call cake      :... NG orz
  call Ethna     :... NG orz
  call symfony_1   :... NG orz
  call symfony_2   :... NG orz
  call php_filter   :... NG orz

 !#$%&'*+-/=?^_`.{|}~@example.com (使用可能な記号の群れ)
  call phpspot    :... NG orz
  call idea      :... NG orz
  call tabo_purify  :... NG orz
  call doli      :... NG orz
  call seesaa     :... NG orz
  call yachin29    :... NG orz
  call doremi_1    :... NG orz
  call doremi_2    :... NG orz
  call mpyw      :... OK!!
  call fdays_2    :... NG orz
  call fdays_3    :... NG orz
  call pear      :... OK!!
  call cake      :... NG orz
  call Ethna     :... NG orz
  call symfony_1   :... OK!!
  call symfony_2   :... OK!!
  call php_filter   :... OK!!

 "da.me.."@example.com (これは「quoted string」なのでvalidなパターンその1)
  call phpspot    :... NG orz
  call idea      :... NG orz
  call tabo_purify  :... NG orz
  call doli      :... NG orz
  call seesaa     :... NG orz
  call yachin29    :... NG orz
  call doremi_1    :... NG orz
  call doremi_2    :... NG orz
  call mpyw      :... OK!!
  call fdays_2    :... NG orz
  call fdays_3    :... NG orz
  call pear      :... NG orz
  call cake      :... NG orz
  call Ethna     :... NG orz
  call symfony_1   :... OK!!
  call symfony_2   :... OK!!
  call php_filter   :... OK!!

 "nobody@nobody"@example.com (これは「quoted string」なのでvalidなパターンその2)
  call phpspot    :... NG orz
  call idea      :... NG orz
  call tabo_purify  :... NG orz
  call doli      :... NG orz
  call seesaa     :... NG orz
  call yachin29    :... NG orz
  call doremi_1    :... NG orz
  call doremi_2    :... NG orz
  call mpyw      :... OK!!
  call fdays_2    :... NG orz
  call fdays_3    :... NG orz
  call pear      :... NG orz
  call cake      :... NG orz
  call Ethna     :... NG orz
  call symfony_1   :... OK!!
  call symfony_2   :... NG orz
  call php_filter   :... OK!!

 nobody+regexp@gmail.com (いわゆる拡張アドレスその1)
  call phpspot    :... NG orz
  call idea      :... NG orz
  call tabo_purify  :... NG orz
  call doli      :... OK!!
  call seesaa     :... OK!!
  call yachin29    :... NG orz
  call doremi_1    :... NG orz
  call doremi_2    :... NG orz
  call mpyw      :... OK!!
  call fdays_2    :... OK!!
  call fdays_3    :... OK!!
  call pear      :... OK!!
  call cake      :... OK!!
  call Ethna     :... OK!!
  call symfony_1   :... OK!!
  call symfony_2   :... OK!!
  call php_filter   :... OK!!

 nobody-regexp@gmail.com (いわゆる拡張アドレスその2)
  call phpspot    :... OK!!
  call idea      :... NG orz
  call tabo_purify  :... OK!!
  call doli      :... OK!!
  call seesaa     :... OK!!
  call yachin29    :... OK!!
  call doremi_1    :... OK!!
  call doremi_2    :... OK!!
  call mpyw      :... OK!!
  call fdays_2    :... OK!!
  call fdays_3    :... OK!!
  call pear      :... OK!!
  call cake      :... OK!!
  call Ethna     :... OK!!
  call symfony_1   :... OK!!
  call symfony_2   :... OK!!
  call php_filter   :... OK!!

 "nobody+regexp"@gmail.com (いわゆる拡張アドレスその3(拡張+quoted))
  call phpspot    :... NG orz
  call idea      :... NG orz
  call tabo_purify  :... NG orz
  call doli      :... NG orz
  call seesaa     :... NG orz
  call yachin29    :... NG orz
  call doremi_1    :... NG orz
  call doremi_2    :... NG orz
  call mpyw      :... OK!!
  call fdays_2    :... NG orz
  call fdays_3    :... NG orz
  call pear      :... NG orz
  call cake      :... NG orz
  call Ethna     :... NG orz
  call symfony_1   :... OK!!
  call symfony_2   :... OK!!
  call php_filter   :... OK!!

 "nobody-regexp"@gmail.com (いわゆる拡張アドレスその4(拡張+quoted))
  call phpspot    :... NG orz
  call idea      :... NG orz
  call tabo_purify  :... NG orz
  call doli      :... NG orz
  call seesaa     :... NG orz
  call yachin29    :... NG orz
  call doremi_1    :... NG orz
  call doremi_2    :... NG orz
  call mpyw      :... OK!!
  call fdays_2    :... NG orz
  call fdays_3    :... NG orz
  call pear      :... NG orz
  call cake      :... NG orz
  call Ethna     :... NG orz
  call symfony_1   :... OK!!
  call symfony_2   :... OK!!
  call php_filter   :... OK!!



call phpspot    
 invalid
  da.me.@example.com      ... NG orz(local-part最後の.(ドット)はNG)
  da..me@example.com      ... NG orz(連続した.(ドット)はNG)
  da.me@example.com_      ... NG orz(domain-partの最後はアルファベットまたは数字のみ)
  da.me@example.com.      ... NG orz(domain-partの最後はアルファベットまたは数字のみ(その2))
  nobody@add_example.com    ... NG orz(domain-partのアンダースコアはNG)
 valid
  !nobody@example.com      ... NG orz(先頭を記号に)
  Abc\@def@example.com     ... NG orz(quoted pair(ただしこれはobsolete))
  !#$%&'*+-/=?^_`.{|}~@example.com... NG orz(使用可能な記号の群れ)
  "da.me.."@example.com     ... NG orz(これは「quoted string」なのでvalidなパターンその1)
  "nobody@nobody"@example.com  ... NG orz(これは「quoted string」なのでvalidなパターンその2)
  nobody+regexp@gmail.com    ... NG orz(いわゆる拡張アドレスその1)
  "nobody+regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその3(拡張+quoted))
  "nobody-regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその4(拡張+quoted))

call idea     
 invalid
  .da.me@example.com      ... NG orz(local-part先頭の.(ドット)はNG)
  nobody@add_example.com    ... NG orz(domain-partのアンダースコアはNG)
 valid
  0nobody@example.com      ... NG orz(先頭を数字に)
  Abc\@def@example.com     ... NG orz(quoted pair(ただしこれはobsolete))
  !#$%&'*+-/=?^_`.{|}~@example.com... NG orz(使用可能な記号の群れ)
  "da.me.."@example.com     ... NG orz(これは「quoted string」なのでvalidなパターンその1)
  "nobody@nobody"@example.com  ... NG orz(これは「quoted string」なのでvalidなパターンその2)
  nobody+regexp@gmail.com    ... NG orz(いわゆる拡張アドレスその1)
  nobody-regexp@gmail.com    ... NG orz(いわゆる拡張アドレスその2)
  "nobody+regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその3(拡張+quoted))
  "nobody-regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその4(拡張+quoted))

call tabo_purify  
 invalid
  .da.me@example.com      ... NG orz(local-part先頭の.(ドット)はNG)
  da.me.@example.com      ... NG orz(local-part最後の.(ドット)はNG)
  da..me@example.com      ... NG orz(連続した.(ドット)はNG)
 valid
  !nobody@example.com      ... NG orz(先頭を記号に)
  Abc\@def@example.com     ... NG orz(quoted pair(ただしこれはobsolete))
  !#$%&'*+-/=?^_`.{|}~@example.com... NG orz(使用可能な記号の群れ)
  "da.me.."@example.com     ... NG orz(これは「quoted string」なのでvalidなパターンその1)
  "nobody@nobody"@example.com  ... NG orz(これは「quoted string」なのでvalidなパターンその2)
  nobody+regexp@gmail.com    ... NG orz(いわゆる拡張アドレスその1)
  "nobody+regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその3(拡張+quoted))
  "nobody-regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその4(拡張+quoted))

call doli     
 invalid
 valid
  !nobody@example.com      ... NG orz(先頭を記号に)
  Abc\@def@example.com     ... NG orz(quoted pair(ただしこれはobsolete))
  !#$%&'*+-/=?^_`.{|}~@example.com... NG orz(使用可能な記号の群れ)
  "da.me.."@example.com     ... NG orz(これは「quoted string」なのでvalidなパターンその1)
  "nobody@nobody"@example.com  ... NG orz(これは「quoted string」なのでvalidなパターンその2)
  "nobody+regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその3(拡張+quoted))
  "nobody-regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその4(拡張+quoted))

call seesaa    
 invalid
  .da.me@example.com      ... NG orz(local-part先頭の.(ドット)はNG)
  da.me.@example.com      ... NG orz(local-part最後の.(ドット)はNG)
  da..me@example.com      ... NG orz(連続した.(ドット)はNG)
  da.me@.example.com      ... NG orz(domain-part先頭の.(ドット)はNG)
  nobody@add_example.com    ... NG orz(domain-partのアンダースコアはNG)
 valid
  Abc\@def@example.com     ... NG orz(quoted pair(ただしこれはobsolete))
  !#$%&'*+-/=?^_`.{|}~@example.com... NG orz(使用可能な記号の群れ)
  "da.me.."@example.com     ... NG orz(これは「quoted string」なのでvalidなパターンその1)
  "nobody@nobody"@example.com  ... NG orz(これは「quoted string」なのでvalidなパターンその2)
  "nobody+regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその3(拡張+quoted))
  "nobody-regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその4(拡張+quoted))

call yachin29   
 invalid
  da.me.@example.com      ... NG orz(local-part最後の.(ドット)はNG)
  da..me@example.com      ... NG orz(連続した.(ドット)はNG)
  da.me@example.com_      ... NG orz(domain-partの最後はアルファベットまたは数字のみ)
  da.me@example.com.      ... NG orz(domain-partの最後はアルファベットまたは数字のみ(その2))
  nobody@add_example.com    ... NG orz(domain-partのアンダースコアはNG)
 valid
  !nobody@example.com      ... NG orz(先頭を記号に)
  Abc\@def@example.com     ... NG orz(quoted pair(ただしこれはobsolete))
  !#$%&'*+-/=?^_`.{|}~@example.com... NG orz(使用可能な記号の群れ)
  "da.me.."@example.com     ... NG orz(これは「quoted string」なのでvalidなパターンその1)
  "nobody@nobody"@example.com  ... NG orz(これは「quoted string」なのでvalidなパターンその2)
  nobody+regexp@gmail.com    ... NG orz(いわゆる拡張アドレスその1)
  "nobody+regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその3(拡張+quoted))
  "nobody-regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその4(拡張+quoted))

call doremi_1   
 invalid
  .da.me@example.com      ... NG orz(local-part先頭の.(ドット)はNG)
  da.me.@example.com      ... NG orz(local-part最後の.(ドット)はNG)
  da..me@example.com      ... NG orz(連続した.(ドット)はNG)
  da.me@.example.com      ... NG orz(domain-part先頭の.(ドット)はNG)
  da.me@example.com_      ... NG orz(domain-partの最後はアルファベットまたは数字のみ)
  da.me@example.com.      ... NG orz(domain-partの最後はアルファベットまたは数字のみ(その2))
  nobody@add_example.com    ... NG orz(domain-partのアンダースコアはNG)
 valid
  !nobody@example.com      ... NG orz(先頭を記号に)
  Abc\@def@example.com     ... NG orz(quoted pair(ただしこれはobsolete))
  !#$%&'*+-/=?^_`.{|}~@example.com... NG orz(使用可能な記号の群れ)
  "da.me.."@example.com     ... NG orz(これは「quoted string」なのでvalidなパターンその1)
  "nobody@nobody"@example.com  ... NG orz(これは「quoted string」なのでvalidなパターンその2)
  nobody+regexp@gmail.com    ... NG orz(いわゆる拡張アドレスその1)
  "nobody+regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその3(拡張+quoted))
  "nobody-regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその4(拡張+quoted))

call doremi_2   
 invalid
  da.me@example.com_      ... NG orz(domain-partの最後はアルファベットまたは数字のみ)
  nobody@add_example.com    ... NG orz(domain-partのアンダースコアはNG)
 valid
  !nobody@example.com      ... NG orz(先頭を記号に)
  Abc\@def@example.com     ... NG orz(quoted pair(ただしこれはobsolete))
  !#$%&'*+-/=?^_`.{|}~@example.com... NG orz(使用可能な記号の群れ)
  "da.me.."@example.com     ... NG orz(これは「quoted string」なのでvalidなパターンその1)
  "nobody@nobody"@example.com  ... NG orz(これは「quoted string」なのでvalidなパターンその2)
  nobody+regexp@gmail.com    ... NG orz(いわゆる拡張アドレスその1)
  "nobody+regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその3(拡張+quoted))
  "nobody-regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその4(拡張+quoted))

call mpyw     
 invalid
 valid
  nobody@1st.example.com    ... NG orz(ドメイン名の先頭を数字に(昔は駄目だった))
  Abc\@def@example.com     ... NG orz(quoted pair(ただしこれはobsolete))

call fdays_2    
 invalid
 valid
  !nobody@example.com      ... NG orz(先頭を記号に)
  Abc\@def@example.com     ... NG orz(quoted pair(ただしこれはobsolete))
  !#$%&'*+-/=?^_`.{|}~@example.com... NG orz(使用可能な記号の群れ)
  "da.me.."@example.com     ... NG orz(これは「quoted string」なのでvalidなパターンその1)
  "nobody@nobody"@example.com  ... NG orz(これは「quoted string」なのでvalidなパターンその2)
  "nobody+regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその3(拡張+quoted))
  "nobody-regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその4(拡張+quoted))

call fdays_3    
 invalid
  .da.me@example.com      ... NG orz(local-part先頭の.(ドット)はNG)
  da.me.@example.com      ... NG orz(local-part最後の.(ドット)はNG)
  da..me@example.com      ... NG orz(連続した.(ドット)はNG)
 valid
  !nobody@example.com      ... NG orz(先頭を記号に)
  Abc\@def@example.com     ... NG orz(quoted pair(ただしこれはobsolete))
  !#$%&'*+-/=?^_`.{|}~@example.com... NG orz(使用可能な記号の群れ)
  "da.me.."@example.com     ... NG orz(これは「quoted string」なのでvalidなパターンその1)
  "nobody@nobody"@example.com  ... NG orz(これは「quoted string」なのでvalidなパターンその2)
  "nobody+regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその3(拡張+quoted))
  "nobody-regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその4(拡張+quoted))

call pear     
 invalid
  .da.me@example.com      ... NG orz(local-part先頭の.(ドット)はNG)
  da.me.@example.com      ... NG orz(local-part最後の.(ドット)はNG)
  da..me@example.com      ... NG orz(連続した.(ドット)はNG)
 valid
  Abc\@def@example.com     ... NG orz(quoted pair(ただしこれはobsolete))
  "da.me.."@example.com     ... NG orz(これは「quoted string」なのでvalidなパターンその1)
  "nobody@nobody"@example.com  ... NG orz(これは「quoted string」なのでvalidなパターンその2)
  "nobody+regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその3(拡張+quoted))
  "nobody-regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその4(拡張+quoted))

call cake     
 invalid
  da.me.@example.com      ... NG orz(local-part最後の.(ドット)はNG)
  da..me@example.com      ... NG orz(連続した.(ドット)はNG)
 valid
  !nobody@example.com      ... NG orz(先頭を記号に)
  Abc\@def@example.com     ... NG orz(quoted pair(ただしこれはobsolete))
  !#$%&'*+-/=?^_`.{|}~@example.com... NG orz(使用可能な記号の群れ)
  "da.me.."@example.com     ... NG orz(これは「quoted string」なのでvalidなパターンその1)
  "nobody@nobody"@example.com  ... NG orz(これは「quoted string」なのでvalidなパターンその2)
  "nobody+regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその3(拡張+quoted))
  "nobody-regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその4(拡張+quoted))

call Ethna     
 invalid
  .da.me@example.com      ... NG orz(local-part先頭の.(ドット)はNG)
  da.me.@example.com      ... NG orz(local-part最後の.(ドット)はNG)
  da..me@example.com      ... NG orz(連続した.(ドット)はNG)
  nobody@add_example.com    ... NG orz(domain-partのアンダースコアはNG)
 valid
  !nobody@example.com      ... NG orz(先頭を記号に)
  Abc\@def@example.com     ... NG orz(quoted pair(ただしこれはobsolete))
  !#$%&'*+-/=?^_`.{|}~@example.com... NG orz(使用可能な記号の群れ)
  "da.me.."@example.com     ... NG orz(これは「quoted string」なのでvalidなパターンその1)
  "nobody@nobody"@example.com  ... NG orz(これは「quoted string」なのでvalidなパターンその2)
  "nobody+regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその3(拡張+quoted))
  "nobody-regexp"@gmail.com   ... NG orz(いわゆる拡張アドレスその4(拡張+quoted))

call symfony_1   
 invalid
  da.me@example.com_      ... NG orz(domain-partの最後はアルファベットまたは数字のみ)
  nobody@add_example.com    ... NG orz(domain-partのアンダースコアはNG)
 valid
  Abc\@def@example.com     ... NG orz(quoted pair(ただしこれはobsolete))

call symfony_2   
 invalid
  .da.me@example.com      ... NG orz(local-part先頭の.(ドット)はNG)
  da.me.@example.com      ... NG orz(local-part最後の.(ドット)はNG)
  da..me@example.com      ... NG orz(連続した.(ドット)はNG)
 valid
  Abc\@def@example.com     ... NG orz(quoted pair(ただしこれはobsolete))
  "nobody@nobody"@example.com  ... NG orz(これは「quoted string」なのでvalidなパターンその2)

call php_filter  
 invalid
 valid
  Abc\@def@example.com     ... NG orz(quoted pair(ただしこれはobsolete))

phpspot
  OK => 7
  NG => 13
idea
  OK => 9
  NG => 11
tabo_purify
  OK => 9
  NG => 11
doli
  OK => 13
  NG => 7
seesaa
  OK => 9
  NG => 11
yachin29
  OK => 7
  NG => 13
doremi_1
  OK => 5
  NG => 15
doremi_2
  OK => 10
  NG => 10
mpyw
  OK => 18
  NG => 2
fdays_2
  OK => 13
  NG => 7
fdays_3
  OK => 10
  NG => 10
pear
  OK => 12
  NG => 8
cake
  OK => 11
  NG => 9
Ethna
  OK => 9
  NG => 11
symfony_1
  OK => 17
  NG => 3
symfony_2
  OK => 15
  NG => 5
php_filter
  OK => 19
  NG => 1