电子邮件地址的正则表达式不接受'&' 'dot'之前

时间:2013-05-20 14:01:36

标签: regex

这是验证phpbb中电子邮件地址的功能的一部分。 我有一个有效的电子邮件地址

“pwd-p& r2.coop @ ...”但验证不接受。

有趣的是,当我尝试“pwd-pr2.co& op @ ...”时(在'dot'之后带'&')

和“pwd-pr& 2coop @ ...”(没有'dot'),两者都有效,

但是“pwd-pr& 2.coop @ ...”(在'&'之后带有'dot')不是。

我试图将正则表达式更改几天,但仍然没有弄清楚如何修复它以便它接受我的电子邮件地址。

function get_preg_expression($mode)
{
    switch ($mode)
    {
        case 'email':
        // Regex written by James Watts and Francisco Jose Martin Moreno
        // http://fightingforalostcause.net/misc/2006/compare-email-regex.php
        return '([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*(?:[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]|&)+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,63})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)';
    break;
    }
}

2 个答案:

答案 0 :(得分:3)

电子邮件不应该使用正则表达式进行验证,正是因为这个问题正在发生的原因 - 它很复杂,而且几乎没有人能做到正确。

PHP具有filter_var()函数形式的内置电子邮件验证程序。这通常是验证电子邮件的最佳选择。

这是一行代码,根本不需要任何复杂的正则表达式。

从上述链接复制的示例(即PHP手册):

<?php
$email_a = 'joe@example.com';
$email_b = 'bogus';

if (filter_var($email_a, FILTER_VALIDATE_EMAIL)) {
    echo "This (email_a) email address is considered valid.";
}
if (filter_var($email_b, FILTER_VALIDATE_EMAIL)) {
    echo "This (email_b) email address is considered valid.";
}
?>

希望有所帮助。

答案 1 :(得分:1)

试试这个:

function get_preg_expression($mode)
{
    switch ($mode)
    {
        case 'email':
        // Regex written by James Watts and Francisco Jose Martin Moreno
        // http://fightingforalostcause.net/misc/2006/compare-email-regex.php
        // return '^(?:[\w!#$%&\'*+-\/=?^`{|}~]+\.)*(?:[\w!#$%&\'*+-\/=?^`{|}~]|&amp;)+$';
        return '(?:[\w!#$%&\'*+-\/=?^`{|}~]+\.)*(?:[\w!#$%&\'*+-\/=?^`{|}~]|&amp;)+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,63})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)';
    break;
    }
}

我没有在前导括号表达式中转义不需要转义的字符。这似乎已经成功了。更具体地说,我留下的唯一字符是:(a)',由于PHP字符串转义语法,和(b)/,因为我使用/作为PHP的preg分隔符。< / p>

遗憾的是,我没有关于为什么这种失败帮助的理论。然而,这是一个最好的做法,只是为了逃避需要逃避的东西,所以我根据你“应该”做的事情来达到解决方案,所以我很乐意分享。答案并不令人满意,但至少它似乎有效。

这是我用于测试的测试工具,如果它有用,加上匹配:

function get_preg_expression($mode)
{
    switch ($mode)
    {
        case 'email':
        // Regex written by James Watts and Francisco Jose Martin Moreno
        // http://fightingforalostcause.net/misc/2006/compare-email-regex.php
        // return '^(?:[\w!#$%&\'*+-\/=?^`{|}~]+\.)*(?:[\w!#$%&\'*+-\/=?^`{|}~]|&amp;)+$';
        return '(?:[\w!#$%&\'*+-\/=?^`{|}~]+\.)*(?:[\w!#$%&\'*+-\/=?^`{|}~]|&amp;)+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,63})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)';
    break;
    }
}

var_dump(preg_match('/' . get_preg_expression('email') . '/', 'pwd-pr&2coop@hello.com')); // Matches
var_dump(preg_match('/' . get_preg_expression('email') . '/', 'pwd-pr&2.coop@hello.com')); // Matches
var_dump(preg_match('/' . get_preg_expression('email') . '/', 'pwd-p&r2.coop@hello.com')); // Matches
var_dump(preg_match('/' . get_preg_expression('email') . '/', 'hello')); // Does not match
var_dump(preg_match('/' . get_preg_expression('email') . '/', 'hello@world')); // Does not match
var_dump(preg_match('/' . get_preg_expression('email') . '/', 'hello@world.com')); // Matches