我有这个功能来验证一个电子邮件地址:

function validateEMAIL($EMAIL) {
    $v = "/[a-zA-Z0-9_-.+]+@[a-zA-Z0-9-]+.[a-zA-Z]+/";

    return (bool)preg_match($v, $EMAIL);
}

这样可以检查电子邮件地址是否有效吗?


当前回答

检查电子邮件地址是否格式良好的最简单和最安全的方法是使用filter_var()函数:

if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    // invalid emailaddress
}

此外,您可以检查域是否定义了MX记录:

if (!checkdnsrr($domain, 'MX')) {
    // domain is not valid
}

但这仍然不能保证邮件存在。唯一的办法就是发送确认邮件。


现在你已经有了简单的答案,如果你想学习,可以继续阅读关于电子邮件地址验证的内容,或者只是使用快速答案并继续前进。别见怪不怪。

尝试使用正则表达式验证电子邮件地址是一项“不可能”的任务。我想说的是,你所做的正则表达式是无用的。关于电子邮件地址有三个rfc,编写一个正则表达式来捕获错误的电子邮件地址,同时避免误报,这是没有人能做到的。查看PHP的filter_var()函数所使用的正则表达式的测试列表(包括失败和成功)。

即使是内置的PHP函数,电子邮件客户端或服务器也没有做到这一点。在大多数情况下,filter_var仍然是最好的选择。

如果你想知道PHP(目前)使用哪种正则表达式模式来验证电子邮件地址,请参阅PHP源代码。

如果你想了解更多关于电子邮件地址的信息,我建议你开始阅读说明书,但我必须警告你,无论如何,这都不是一个简单的阅读:

rfc5322 rfc5321 rfc3696 Rfc6531(允许unicode字符,尽管许多客户端/服务器不接受它)

其他回答

/(?![[:alnum:]]|@|-|_|\.)./

现在,如果你使用带有type=email的HTML5表单,那么你已经有80%的安全性了,因为浏览器引擎有它们自己的验证器。为了补充它,将这个正则表达式添加到你的preg_match_all()并对其求反:

if (!preg_match_all("/(?![[:alnum:]]|@|-|_|\.)./",$email)) { .. }

找到HTML5表单使用的正则表达式进行验证 https://regex101.com/r/mPEKmy/1

使用以下代码:

// Variable to check
$email = "john.doe@example.com";

// Remove all illegal characters from email
$email = filter_var($email, FILTER_SANITIZE_EMAIL);


// Validate e-mail
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
  echo("Email is a valid email address");
}

在关于电子邮件验证的“顶级问题”中回答了这个问题https://stackoverflow.com/a/41129750/1848217

For me the right way for checking emails is: Check that symbol @ exists, and before and after it there are some non-@ symbols: /^[^@]+@[^@]+$/ Try to send an email to this address with some "activation code". When the user "activated" his email address, we will see that all is right. Of course, you can show some warning or tooltip in front-end when user typed "strange" email to help him to avoid common mistakes, like no dot in domain part or spaces in name without quoting and so on. But you must accept the address "hello@world" if user really want it. Also, you must remember that email address standard was and can evolute, so you can't just type some "standard-valid" regexp once and for all times. And you must remember that some concrete internet servers can fail some details of common standard and in fact work with own "modified standard".

所以,只要检查@,提示用户在前端和发送验证电子邮件在给定的地址。

如果你只是在寻找一个实际的正则表达式,允许各种点,下划线和破折号,它如下:[a-zA-z0-9.-]+\@[a-zA-z0-9.-]+.[a-zA-Z]+。这将允许像tom_anderson.1-neo@my-mail_matrix.com这样看起来相当愚蠢的电子邮件被验证。

根据我的经验,regex解决方案有太多的假阳性,而filter_var()解决方案有假阴性(特别是对于所有新的tld)。

相反,最好是确保地址具有电子邮件地址的所有必需部分(用户、“@”符号和域),然后验证域本身是否存在。

无法确定(服务器端)外部域是否存在电子邮件用户。

这是我在Utility类中创建的一个方法:

public static function validateEmail(string $email): bool {

    // SET INITIAL RETURN VARIABLE
    // ENSURE -> EMAIL ISN'T EMPTY | AN @ SYMBOL IS PRESENT 

        $emailIsValid = FALSE;

        if (
            !empty($email) &&
            strpos($email, '@') !== FALSE
        ) {

            // GET EMAIL PARTS

                $email  = explode('@', $email);
                $user   = $email[0];
                $domain = $email[1];

            // VALIDATE EMAIL ADDRESS

                if (
                    count($email) === 2 &&
                    !empty($user) &&
                    !empty($domain) &&
                    checkdnsrr($domain)
                ) {
                    $emailIsValid = TRUE;
                }
        }

    // RETURN RESULT

        return $emailIsValid;
}