多年来,我慢慢地开发了一个正则表达式,它可以正确验证大多数电子邮件地址,假设它们不使用IP地址作为服务器部分。

我在几个PHP程序中使用它,而且大多数时候都可以使用。然而,不时有人与我联系,他们对使用它的网站有问题,我最终不得不做出一些调整(最近我意识到我不允许四个字符的TLD)。

你有或见过验证电子邮件的最佳正则表达式是什么?

我见过几种使用函数的解决方案,这些函数使用了几个较短的表达式,但我宁愿在简单函数中使用一个长的复杂表达式,而不是在更复杂的函数中使用几个短表达式。


当前回答

世界上最流行的博客平台WordPress使用此功能验证电子邮件地址。。。

但他们是通过多个步骤来实现的。

使用此函数中提到的正则表达式时,您不必再担心。。。

这是函数。。。

/**
 * Verifies that an email is valid.
 *
 * Does not grok i18n domains. Not RFC compliant.
 *
 * @since 0.71
 *
 * @param string $email Email address to verify.
 * @param boolean $deprecated Deprecated.
 * @return string|bool Either false or the valid email address.
 */
function is_email( $email, $deprecated = false ) {
    if ( ! empty( $deprecated ) )
        _deprecated_argument( __FUNCTION__, '3.0' );

    // Test for the minimum length the email can be
    if ( strlen( $email ) < 3 ) {
        return apply_filters( 'is_email', false, $email, 'email_too_short' );
    }

    // Test for an @ character after the first position
    if ( strpos( $email, '@', 1 ) === false ) {
        return apply_filters( 'is_email', false, $email, 'email_no_at' );
    }

    // Split out the local and domain parts
    list( $local, $domain ) = explode( '@', $email, 2 );

    // LOCAL PART
    // Test for invalid characters
    if ( !preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local ) ) {
        return apply_filters( 'is_email', false, $email, 'local_invalid_chars' );
    }

    // DOMAIN PART
    // Test for sequences of periods
    if ( preg_match( '/\.{2,}/', $domain ) ) {
        return apply_filters( 'is_email', false, $email, 'domain_period_sequence' );
    }

    // Test for leading and trailing periods and whitespace
    if ( trim( $domain, " \t\n\r\0\x0B." ) !== $domain ) {
        return apply_filters( 'is_email', false, $email, 'domain_period_limits' );
    }

    // Split the domain into subs
    $subs = explode( '.', $domain );

    // Assume the domain will have at least two subs
    if ( 2 > count( $subs ) ) {
        return apply_filters( 'is_email', false, $email, 'domain_no_periods' );
    }

    // Loop through each sub
    foreach ( $subs as $sub ) {
        // Test for leading and trailing hyphens and whitespace
        if ( trim( $sub, " \t\n\r\0\x0B-" ) !== $sub ) {
            return apply_filters( 'is_email', false, $email, 'sub_hyphen_limits' );
        }

        // Test for invalid characters
        if ( !preg_match('/^[a-z0-9-]+$/i', $sub ) ) {
            return apply_filters( 'is_email', false, $email, 'sub_invalid_chars' );
        }
    }

    // Congratulations your email made it!
    return apply_filters( 'is_email', $email, $email, null );
}

其他回答

没有一个是真正有用的。我在回答“是否有用于电子邮件地址验证的PHP库?”时讨论了一些问题?,它也在电子邮件地址的正则表达式识别难吗?中讨论?。

简而言之,不要期望一个可用的正则表达式能够完成正确的工作。最好的正则表达式将验证语法,而不是电子邮件的有效性(jhohn@example.com是正确的,但它可能会反弹…)。

列表项目

我使用此功能

function checkmail($value) {
    $value = trim($value);
    if (stristr($value,"@") &&
        stristr($value,".") &&
        (strrpos($value, ".") - stripos($value, "@") > 2) &&
        (stripos($value, "@") > 1) &&
        (strlen($value) - strrpos($value, ".") < 6) &&
        (strlen($value) - strrpos($value, ".") > 2) &&
        ($value == preg_replace('/[ ]/', '', $value)) &&
        ($value == preg_replace('/[^A-Za-z0-9\-_.@!*]/', '', $value))
    )
    {

    }
    else {
        return "Invalid Mail-Id";
    }
}

为所有内容编写正则表达式需要花费大量的精力。相反,您可以使用pyIsEmail包。

以下文字摘自pyIsEmail网站。

pyIsEmail是一种无意义的方法,用于检查用户提供的电子邮件地址是否真实。

正则表达式编写起来很便宜,但当新的顶级域出现或不符合重新流行的电子邮件寻址功能时,通常需要维护。pyIsEmail允许您通过一个简单的调用来验证电子邮件地址,如果您愿意的话,甚至可以检查域,从而使您的代码更易读,编写速度更快。当你想知道为什么电子邮件地址无法验证时,他们甚至会为你提供诊断。

用法

对于最简单的用法,请导入并使用is_email函数:

from pyisemail import is_email

address = "test@example.com"
bool_result = is_email(address)
detailed_result = is_email(address, diagnose=True)

您还可以检查电子邮件中使用的域是否为有效域,以及它是否具有有效的MX记录:

from pyisemail import is_email

address = "test@example.com"
bool_result_with_dns = is_email(address, check_dns=True)
detailed_result_with_dns = is_email(address, check_dns=True, diagnose=True)

这些是电子邮件地址是否可以在该域发出的主要指标。然而,这里的有效回复并不能保证电子邮件存在,仅仅是它可以存在。

除了基本的is_email功能之外,您还可以单独使用验证器。检查验证器源文档以了解其工作原理。

此规则与Postfix服务器无法发送的内容相匹配。

允许使用字母、数字、-、_、+、.、&、/、,和

不-foo@bar.com

不asd@-bar.com

/^([a-z0-9\+\._\/&!][-a-z0-9\+\._\/&!]*)@(([a-z0-9][-a-z0-9]*\.)([-a-z0-9]+\.)*[a-z]{2,})$/i

我要验证的电子邮件地址将由使用System.NET.Mail命名空间的ASP.NET web应用程序用于向人员列表发送电子邮件。

因此,我不使用一些非常复杂的正则表达式,而是尝试从地址创建一个MailAddress实例。如果地址格式不正确,MailAddress构造函数将引发异常。通过这种方式,我知道我至少可以把邮件拿到门外。当然,这是服务器端验证,但至少您需要这样做。

protected void emailValidator_ServerValidate(object source, ServerValidateEventArgs args)
{
    try
    {
        var a = new MailAddress(txtEmail.Text);
    }
    catch (Exception ex)
    {
        args.IsValid = false;
        emailValidator.ErrorMessage = "email: " + ex.Message;
    }
}