Php 为什么这个正则表达式用于验证特定域';电子邮件不起作用?

Php 为什么这个正则表达式用于验证特定域';电子邮件不起作用?,php,regex,Php,Regex,我正在使用PHPpreg_match函数验证我们公司的电子邮件,其形式可以是user@mycompany.com或使用子域,如user@marketing.mycompany.com或user@it.mycompany.com return (preg_match("/^[a-zA-Z0-9_-.+]+@[a-zA-Z0-9-]+.[a-zA-Z]+(\.?mycompany\.com)$/", $testEmail) > 0) 但是,对于上面提到的所有示例,validEmail函数都返

我正在使用PHP
preg_match
函数验证我们公司的电子邮件,其形式可以是
user@mycompany.com
或使用子域,如
user@marketing.mycompany.com
user@it.mycompany.com

return (preg_match("/^[a-zA-Z0-9_-.+]+@[a-zA-Z0-9-]+.[a-zA-Z]+(\.?mycompany\.com)$/", $testEmail) > 0)

但是,对于上面提到的所有示例,validEmail函数都返回false。为什么?

因为你忘了逃出一个
和一个
-
。此外,未在
“@”
mycompany.com
之间创建字符块会导致匹配问题
user@mycompany.com
。尝试:

return (preg_match("/^[a-zA-Z0-9_\-.+]+@(?:[a-zA-Z0-9\-]+(?:\.[a-zA-Z])?)?(\.?mycompany\.com)$/", $testEmail) > 0)
  • 有一个内置的电子邮件验证功能——它至少在99%的情况下都能正常工作,与您的regexp相反
  • 用于从电子邮件地址获取主机名,并检查其是否以
    mycompany.com
    结尾:

    $hostname = parse_url($email, PHP_URL_HOST);
    
    if (substr($hostname, strlen('mycompany.com') * -1)) == 'mycompany.com') {
        // ends with "mycompany.com"
    }
    
  • 结合以上内容检查给定的电子邮件地址是否符合您的标准

    • 第三级和第四级域不是可选的(
      ()?
      ),这排除了@mycompany.com和@onesubonly.mycompany.com的任何内容
    • 您忘记退出
    • 我的语法检查不喜欢第一个字符类中的未转义破折号,但据我所知,它在哪里并不重要
    关于电子邮件正则表达式主题的有趣事情(请参阅“.@mycompany.com”等内容,您的主题将被忽略):

    假设您进行了Jack Maney建议的修复:

    匹配“@”字符后,您将与

    [a-zA-Z0-9-]+\.[a-zA-Z]+(\.?mycompany\.com)$
    
    因此,它将无法匹配”blah@mycompany.com“因为它必须匹配字母数字/连字符,然后是点,然后是字母,然后是(.?)mycompany.com。它将匹配“blah@a.b.mycompany.com"

    要修复此问题,请尝试以下正则表达式:

     /^[a-zA-Z0-9_-.+]+@([a-zA-Z0-9-]+\.)*mycompany\.com$/
    
    请注意,现在,在“@”之后,它允许0个或多个

     [a-zA-Z0-9-]+\.
    

    表示子域的

    是否确定所有子域都返回false?我明白为什么
    user@mycompany.com
    user@it.mycompany.com
    (在
    @
    \.?mycompany\.com
    之间没有足够的字符),但我希望它在
    user@marketing.mycompany.com
    。我不相信这对他们中的任何人都有效。我刚测试过。@DavidFaux-现在试试。我在你的问题中给出的三个虚拟电子邮件地址上测试了它,它适用于所有这些地址。
     [a-zA-Z0-9-]+\.