php中,进行RFC兼容的电子邮件地址验证的方法,有需要的朋友参考下吧。
分享一个可以验证RFC兼容的电子邮件地址的代码,支持RFC1123,2396,3696,4291,4343,5321等的验证。

甚至可以验证IPv6地址中的域名部分,实在是强大。

代码:

复制代码代码示例:

<? 
/* 
Copyright 2009 Dominic Sayers 
(dominic_sayers@hotmail.com) 
(http://www.dominicsayers.com)

This source file is subject to the Common Public Attribution License Version 1.0 (CPAL) license. 
The license terms are available through the world-wide-web at http://www.opensource.org/licenses/cpal_1.0 
*/ 
function is_email ($email, $checkDNS = false) { 
    //    Check that $email is a valid address 
    //        (http://tools.ietf.org/html/rfc3696) 
    //        (http://tools.ietf.org/html/rfc5322#section-3.4.1) 
    //        (http://tools.ietf.org/html/rfc5321#section-4.1.3) 
    //        (http://tools.ietf.org/html/rfc4291#section-2.2) 
    //        (http://tools.ietf.org/html/rfc1123#section-2.1) 
     
    //    Contemporary email addresses consist of a "local part" separated from 
    //    a "domain part" (a fully-qualified domain name) by an at-sign ("@"). 
    //        (http://tools.ietf.org/html/rfc3696#section-3) 
    $index = strrpos($email,'@');

if ($index === false)        return false;    //    No at-sign 
    if ($index === 0)            return false;    //    No local part 
    if ($index > 64)            return false;    //    Local part too long

$localPart        = substr($email, 0, $index); 
    $domain            = substr($email, $index + 1); 
    $domainLength    = strlen($domain); 
     
    if ($domainLength === 0)    return false;    //    No domain part 
    if ($domainLength > 255)    return false;    //    Domain part too long

//    Let's check the local part for RFC compliance... 
    // 
    //    Period (".") may...appear, but may not be used to start or end the 
    //    local part, nor may two or more consecutive periods appear. 
    //        (http://tools.ietf.org/html/rfc3696#section-3) 
    if (preg_match('/^\\.|\\.\\.|\\.$/', $localPart) > 0)                return false;    //    Dots in wrong place

//    Any ASCII graphic (printing) character other than the 
    //    at-sign ("@"), backslash, double quote, comma, or square brackets may 
    //    appear without quoting.  If any of that list of excluded characters 
    //    are to appear, they must be quoted 
    //        (http://tools.ietf.org/html/rfc3696#section-3) 
    if (preg_match('/^"(?:.)*"$/', $localPart) > 0) { 
        //    Local part is a quoted string 
        if (preg_match('/(?:.)+[^\\\\]"(?:.)+/', $localPart) > 0)    return false;    //    Unescaped quote character inside quoted string 
    } else { 
        if (preg_match('/[ @\\[\\]\\\\",]/', $localPart) > 0) 
            //    Check all excluded characters are escaped 
            $stripped = preg_replace('/\\\\[ @\\[\\]\\\\",]/', '', $localPart); 
            if (preg_match('/[ @\\[\\]\\\\",]/', $stripped) > 0)        return false;    //    Unquoted excluded characters 
    }

//    Now let's check the domain part...

//    The domain name can also be replaced by an IP address in square brackets 
    //        (http://tools.ietf.org/html/rfc3696#section-3) 
    //        (http://tools.ietf.org/html/rfc5321#section-4.1.3) 
    //        (http://tools.ietf.org/html/rfc4291#section-2.2) 
    if (preg_match('/^\\[(.)+]$/', $domain) === 1) { 
        //    It's an address-literal 
        $addressLiteral = substr($domain, 1, $domainLength - 2); 
        $matchesIP        = array(); 
         
        //    Extract IPv4 part from the end of the address-literal (if there is one) 
        if (preg_match('/\\b(?:(?: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]?)$/', $addressLiteral, $matchesIP) > 0) { 
            $index = strrpos($addressLiteral, $matchesIP[0]); 
             
            if ($index === 0) { 
                //    Nothing there except a valid IPv4 address, so... 
                return true; 
            } else { 
                //    Assume it's an attempt at a mixed address (IPv6 + IPv4) 
                if ($addressLiteral[$index - 1] !== ':')            return false;    //    Character preceding IPv4 address must be ':' 
                if (substr($addressLiteral, 0, 5) !== 'IPv6:')        return false;    //    RFC5321 section 4.1.3

$IPv6 = substr($addressLiteral, 5, ($index ===7) ? 2 : $index - 6); 
                $groupMax = 6; 
            } 
        } else { 
            //    It must be an attempt at pure IPv6 
            if (substr($addressLiteral, 0, 5) !== 'IPv6:')            return false;    //    RFC5321 section 4.1.3 
            $IPv6 = substr($addressLiteral, 5); 
            $groupMax = 8; 
        }

$groupCount    = preg_match_all('/^[0-9a-fA-F]{0,4}|\\:[0-9a-fA-F]{0,4}|(.)/', $IPv6, $matchesIP); 
        $index        = strpos($IPv6,'::');

if ($index === false) { 
            //    We need exactly the right number of groups 
            if ($groupCount !== $groupMax)                            return false;    //    RFC5321 section 4.1.3 
        } else { 
            if ($index !== strrpos($IPv6,'::'))                        return false;    //    More than one '::' 
            $groupMax = ($index === 0 || $index === (strlen($IPv6) - 2)) ? $groupMax : $groupMax - 1; 
            if ($groupCount > $groupMax)                            return false;    //    Too many IPv6 groups in address 
        }

//    Check for unmatched characters 
        array_multisort($matchesIP[1], SORT_DESC); 
        if ($matchesIP[1][0] !== '')                                    return false;    //    Illegal characters in address

//    It's a valid IPv6 address, so... 
        return true; 
    } else { 
        //    It's a domain name...

//    The syntax of a legal Internet host name was specified in RFC-952 
        //    One aspect of host name syntax is hereby changed: the 
        //    restriction on the first character is relaxed to allow either a 
        //    letter or a digit. 
        //        (http://tools.ietf.org/html/rfc1123#section-2.1) 
        // 
        //    NB RFC 1123 updates RFC 1035, but this is not currently apparent from reading RFC 1035. 
        // 
        //    Most common applications, including email and the Web, will generally not permit...escaped strings 
        //        (http://tools.ietf.org/html/rfc3696#section-2) 
        // 
        //    Characters outside the set of alphabetic characters, digits, and hyphen MUST NOT appear in domain name 
        //    labels for SMTP clients or servers 
        //        (http://tools.ietf.org/html/rfc5321#section-4.1.2) 
        // 
        //    RFC5321 precludes the use of a trailing dot in a domain name for SMTP purposes 
        //        (http://tools.ietf.org/html/rfc5321#section-4.1.2) 
        $matches    = array(); 
        $groupCount    = preg_match_all('/(?:[0-9a-zA-Z][0-9a-zA-Z-]{0,61}[0-9a-zA-Z]|[a-zA-Z])(?:\\.|$)|(.)/', $domain, $matches); 
        $level        = count($matches[0]);

if ($level == 1)                                            return false;    //    Mail host can't be a TLD

$TLD = $matches[0][$level - 1]; 
        if (substr($TLD, strlen($TLD) - 1, 1) === '.')                return false;    //    TLD can't end in a dot 
        if (preg_match('/^[0-9]+$/', $TLD) > 0)                        return false;    //    TLD can't be all-numeric

//    Check for unmatched characters 
        array_multisort($matches[1], SORT_DESC); 
        if ($matches[1][0] !== '')                            return false;    //    Illegal characters in domain, or label longer than 63 characters

//    Check DNS? 
        if ($checkDNS && function_exists('checkdnsrr')) { 
            if (!(checkdnsrr($domain, 'A') || checkdnsrr($domain, 'MX'))) { 
                                                                    return false;    //    Domain doesn't actually exist 
            } 
        }

//    Eliminate all other factors, and the one which remains must be the truth. 
        //        (Sherlock Holmes, The Sign of Four) 
        return true; 
    } 
}

function unitTest ($email, $reason = '') { 
    $expected    = ($reason === '') ? true : false; 
    $valid        = is_email($email); 
    $not        = ($valid) ? '' : ' not'; 
    $unexpected    = ($valid !== $expected) ? ' <b>This was unexpected!</b>' : ''; 
    $reason        = ($reason === '') ? "" : " Reason: $reason"; 
     
    return "The address <i>$email</i> is$not valid.$unexpected$reason<br />\n"; 
}

//    Email validator test cases (Dominic Sayers, January 2009) 
//    Valid addresses 
echo unitTest('first.last@example.com'); 
echo unitTest('1234567890123456789012345678901234567890123456789012345678901234@example.com'); 
echo unitTest('"first last"@example.com'); 
echo unitTest('"first\\"last"@example.com');    //    Not totally sure whether this is valid or not 
echo unitTest('first\\@last@example.com'); 
echo unitTest('"first@last"@example.com'); 
echo unitTest('first\\\\last@example.com');    //    Note that \ is escaped even in single-quote strings, so this is testing "first\\last"@example.com 
echo unitTest('first.last@x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.
x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x2345');
echo unitTest('first.last@[12.34.56.78]'); 
echo unitTest('first.last@[IPv6:::12.34.56.78]'); 
echo unitTest('first.last@[IPv6:1111:2222:3333::4444:12.34.56.78]'); 
echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666:12.34.56.78]'); 
echo unitTest('first.last@[IPv6:::1111:2222:3333:4444:5555:6666]'); 
echo unitTest('first.last@[IPv6:1111:2222:3333::4444:5555:6666]'); 
echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666::]'); 
echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888]'); 
echo unitTest('first.last@x23456789012345678901234567890123456789012345678901234567890123.example.com'); 
echo unitTest('first.last@1xample.com'); 
echo unitTest('first.last@123.example.com');

//    Invalid addresses 
echo unitTest('first.last', "No @"); 
echo unitTest('@example.com', "No local part"); 
echo unitTest('12345678901234567890123456789012345678901234567890123456789012345@example.com', "Local part more than 64 characters"); 
echo unitTest('.first.last@example.com', "Local part starts with a dot"); 
echo unitTest('first.last.@example.com', "Local part ends with a dot"); 
echo unitTest('first..last@example.com', "Local part has consecutive dots"); 
echo unitTest('"first"last"@example.com', "Local part contains unescaped excluded characters"); 
echo unitTest('first\\\\@last@example.com', "Local part contains unescaped excluded characters"); 
echo unitTest('first.last@', "No domain"); 
echo unitTest('first.last@x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.
x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456', "Domain exceeds 255 chars");
echo unitTest('first.last@[.12.34.56.78]', "Only char that can precede IPv4 address is ':'"); 
echo unitTest('first.last@[12.34.56.789]', "Can't be interpreted as IPv4 so IPv6 tag is missing"); 
echo unitTest('first.last@[::12.34.56.78]', "IPv6 tag is missing"); 
echo unitTest('first.last@[IPv5:::12.34.56.78]', "IPv6 tag is wrong"); 
echo unitTest('first.last@[IPv6:1111:2222:3333::4444:5555:12.34.56.78]', "Too many IPv6 groups (4 max)"); 
echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:12.34.56.78]', "Not enough IPv6 groups"); 
echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:12.34.56.78]', "Too many IPv6 groups (6 max)"); 
echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777]', "Not enough IPv6 groups"); 
echo unitTest('first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888:9999]', "Too many IPv6 groups (8 max)"); 
echo unitTest('first.last@[IPv6:1111:2222::3333::4444:5555:6666]', "Too many '::' (can be none or one)"); 
echo unitTest('first.last@[IPv6:1111:2222:3333::4444:5555:6666:7777]', "Too many IPv6 groups (6 max)"); 
echo unitTest('first.last@[IPv6:1111:2222:333x::4444:5555]', "x is not valid in an IPv6 address"); 
echo unitTest('first.last@[IPv6:1111:2222:33333::4444:5555]', "33333 is not a valid group in an IPv6 address"); 
echo unitTest('first.last@example.123', "TLD can't be all digits"); 
echo unitTest('first.last@com', "Mail host must be second- or lower level"); 
echo unitTest('first.last@-xample.com', "Label can't begin with a hyphen"); 
echo unitTest('first.last@exampl-.com', "Label can't end with a hyphen"); 
echo unitTest('first.last@x234567890123456789012345678901234567890123456789012345678901234.example.com', "Label can't be longer than 63 octets");

//    Test cases from RFC3696 (February 2004, http://tools.ietf.org/html/rfc3696#section-3) 
echo unitTest('Abc\\@def@example.com'); 
echo unitTest('Fred\\ Bloggs@example.com'); 
echo unitTest('Joe.\\\\Blow@example.com'); 
echo unitTest('"Abc@def"@example.com'); 
echo unitTest('"Fred Bloggs"@example.com'); 
echo unitTest('user+mailbox@example.com'); 
echo unitTest('customer/department=shipping@example.com'); 
echo unitTest('$A12345@example.com'); 
echo unitTest('!def!xyz%abc@example.com'); 
echo unitTest('_somename@example.com');

//    Test cases from Doug Lovell (LinuxJournal, June 2007, http://www.linuxjournal.com/article/9585) 
echo unitTest("dclo@us.ibm.com"); 
echo unitTest("abc\\@def@example.com"); 
echo unitTest("abc\\\\@example.com"); 
echo unitTest("Fred\\ Bloggs@example.com"); 
echo unitTest("Joe.\\\\Blow@example.com"); 
echo unitTest("\"Abc@def\"@example.com"); 
echo unitTest("\"Fred Bloggs\"@example.com"); 
echo unitTest("customer/department=shipping@example.com"); 
echo unitTest("\$A12345@example.com"); 
echo unitTest("!def!xyz%abc@example.com"); 
echo unitTest("_somename@example.com"); 
echo unitTest("user+mailbox@example.com"); 
echo unitTest("peter.piper@example.com"); 
echo unitTest("Doug\\ \\\"Ace\\\"\\ Lovell@example.com"); 
echo unitTest("\"Doug \\\"Ace\\\" L.\"@example.com"); 
echo unitTest("abc@def@example.com", "Doug Lovell says this should fail"); 
echo unitTest("abc\\\\@def@example.com", "Doug Lovell says this should fail"); 
echo unitTest("abc\\@example.com", "Doug Lovell says this should fail"); 
echo unitTest("@example.com", "Doug Lovell says this should fail"); 
echo unitTest("doug@", "Doug Lovell says this should fail"); 
echo unitTest("\"qu@example.com", "Doug Lovell says this should fail"); 
echo unitTest("ote\"@example.com", "Doug Lovell says this should fail"); 
echo unitTest(".dot@example.com", "Doug Lovell says this should fail"); 
echo unitTest("dot.@example.com", "Doug Lovell says this should fail"); 
echo unitTest("two..dot@example.com", "Doug Lovell says this should fail"); 
echo unitTest("\"Doug \"Ace\" L.\"@example.com", "Doug Lovell says this should fail"); 
echo unitTest("Doug\\ \\\"Ace\\\"\\ L\\.@example.com", "Doug Lovell says this should fail"); 
echo unitTest("hello world@example.com", "Doug Lovell says this should fail"); 
echo unitTest("gatsby@f.sc.ot.t.f.i.tzg.era.l.d.", "Doug Lovell says this should fail"); 
?>

本文出处参考:http://www.jbxue.com/article/11340.html

php RFC兼容的电子邮件地址验证的更多相关文章

  1. PHP正则表达式 验证电子邮件地址

    我们最经常遇到的验证,就是电子邮件地址验证.网站上常见.各种网页脚本也都常用“正则表达式”(regular expression)对我们输入的电子邮件地址进行验证,判断是否合法.有的还能分解出用户名和 ...

  2. C++11标准 STL正则表达式 验证电子邮件地址

    转自:http://www.cnblogs.com/yejianfei/archive/2012/10/07/2713715.html 我们最经常遇到的验证,就是电子邮件地址验证.网站上常见.各种网页 ...

  3. shell(sed/gawk)脚本(计算目录文件/验证电话号码/解析电子邮件地址)

    1.计算目录文件 #!/bin/bash mypath=`echo $PATH | sed 's/:/ /g'`#注意` ` 和 ‘ ’ count= for directory in $mypath ...

  4. 验证-- email类型输入框(电子邮件地址)--multiple

    如果需要一个用来填写电子邮件地址的输入框,可以使用email类型.这样浏览器可以帮我们验证格式是否正确,而不需要自己写验证规则.原文:HTML5新控件 - email类型输入框(电子邮件地址) 1,只 ...

  5. [Swift]LeetCode929. 独特的电子邮件地址 | Unique Email Addresses

    Every email consists of a local name and a domain name, separated by the @ sign. For example, in ali ...

  6. 【LeetCode】Unique Email Addresses(独特的电子邮件地址)

    这道题是LeetCode里的第929道题. 题目要求: 每封电子邮件都由一个本地名称和一个域名组成,以 @ 符号分隔. 例如,在 alice@leetcode.com中, alice 是本地名称,而  ...

  7. 【leecode】独特的电子邮件地址

    每封电子邮件都由一个本地名称和一个域名组成,以 @ 符号分隔. 例如,在 alice@leetcode.com中, alice 是本地名称,而 leetcode.com 是域名. 除了小写字母,这些电 ...

  8. leetCode 929 独特的电子邮件地址

    题目: 每封电子邮件都由一个本地名称和一个域名组成,以 @ 符号分隔. 例如,在 alice@leetcode.com中, alice 是本地名称,而 leetcode.com 是域名. 除了小写字母 ...

  9. Leetcode929.Unique Email Addresses独特的电子邮件地址

    每封电子邮件都由一个本地名称和一个域名组成,以 @ 符号分隔. 例如,在 alice@leetcode.com中, alice 是本地名称,而 leetcode.com 是域名. 除了小写字母,这些电 ...

随机推荐

  1. jQuery 实战读书笔记之第六章:事件本质

    理解浏览器事件模型 understandEventModel.html 代码: <!DOCTYPE HTML> <html> <head> <title> ...

  2. UVALive 7712 Confusing Manuscript 字典树 查询与s的编辑距离为1的字符串数量

    /** 题目:UVALive 7712 Confusing Manuscript 链接:https://vjudge.net/problem/UVALive-7712 题意:给定n个不同的字符串,f( ...

  3. C++ 类的多态三(多态的原理--虚函数指针--子类虚函数指针初始化)

    //多态的原理--虚函数指针--子类虚函数指针初始化 #include<iostream> using namespace std; /* 多态的实现原理(有自己猜想部分) 基础知识: 类 ...

  4. 从客户端检测到有潜在危险的Request.Form 值”错误提示

    http://www.cnblogs.com/UouHt/archive/2008/10/30/1322697.html asp.net开发中,经常遇到“从客户端检测到有潜在危险的Request.Fo ...

  5. Pyscripter 不能正确调用另一文件中模块的问题的解析(Internal Engine 和 Remote Engine)

    背景 Pyscripter是python下一个非常流行的开源IDE,笔者一直使用Pyscripter来来编写python脚本. 关于IDE的一些特性本文不在赘述,主要是分享一下今天遇到的一个问题. 问 ...

  6. asp.net调用系统设置字体文本框的方法

    本文实例展示了asp.net调用系统设置字体文本框的方法,是进行web开发中很实用的技巧.具体实现步骤如下: 一.调用系统字体文本框 首先在bin文件夹右击-->添加引用-->.net标签 ...

  7. Java逍遥游记读书笔记<三>

    异常处理 如何判断一个方法中可能抛出异常 该方法中出现throw语句 该方法调用了其他已经带throws子句的方法. 如果方法中可能抛出异常,有两种处理方法: 1.若当前方法有能力处理异常,则用Try ...

  8. Android中的Manifest.permission(应用权限)整理

    ACCESS_CHECKIN_PROPERTIES 允许读/写登记数据库(checkin database),中的“properties”表,用来改变他的值来上传东西. 这个权限第三方应用无法使用. ...

  9. Python_selenium之处理Alert窗

    Python_selenium之处理Alert窗 一.介绍 1. 介绍如何通过switch_to方法处理网页Alert窗口 2. 然后我们自己创建一个alert弹窗进行操作 二.测试脚本 1. 测试脚 ...

  10. Unittest框架概念

    1.测试脚手架(test fixture): 测试准备前要做的工作和测试执行完后要做的工作(包括setUp()和tearDown()) 2.测试用例(test case): 最小的测试单元 3.测试套 ...