使用正则表达式-PCRE-PHP验证包含或不包含子域的域

使用正则表达式-PCRE-PHP验证包含或不包含子域的域,php,regex,pcre,Php,Regex,Pcre,我正在尝试使用最简单的正则表达式形式验证电子邮件地址-而不是- 还需要捕获用户名-子域(如果有)-域和-TLD后缀,即(com、net…) 为此,我提出了以下正则表达式: /^([a-z0-9_\-\.]{6,})+@((?:[a-z0-9\.])*)([a-z0-9_\-]+)[\.]([a-z0-9]{2,})$/i 例如,电子邮件是: username@domain.com username@us.domain.com username@au.domain.com username@us

我正在尝试使用最简单的正则表达式形式验证电子邮件地址-而不是-

还需要捕获用户名-子域(如果有)-域和-TLD后缀,即(com、net…) 为此,我提出了以下正则表达式:

/^([a-z0-9_\-\.]{6,})+@((?:[a-z0-9\.])*)([a-z0-9_\-]+)[\.]([a-z0-9]{2,})$/i
例如,电子邮件是:

username@domain.com
username@us.domain.com
username@au.domain.com
username@us.au.domain.com
正则表达式应该验证它们并捕获所有组


我想知道正则表达式是否正确,还有什么我需要考虑的吗?

最有可能的是你最好用它来获得零件,然后对单独的部分做任何验证。

< P>我已经试了一段时间了,但是我仍然没有得到我一直想要得到的最合适的结果。但这是迄今为止我得到的最接近的结果:

^([a-z0-9_\-\.]{6,24})(?<=[0-9a-z])@((?:[a-z0-9][-\w]*[a-z0-9]*\.)+([a-z]{2,}))$

^([a-z0-9\-\.]{6,24})(?n00p,我看到您还没有找到一个表达式来完全满足您的要求,您说“可能有人会想出更好的解决方案并发布在这里”

这里有一个正则表达式,它可以做你想要的。我已经尽可能少地修改了你自己的表达式,假设你知道你想要什么

为了便于阅读,表达式处于自由间距模式。您可以像使用任何其他正则表达式一样使用它

$regex = "~(?ix) # case-insensitive, free-spacing
^                # assert head of string
([a-z0-9_-]{6,24})    # capture username to Group 1
(?<=[0-9a-z])     # assert that the previous character was a digit or letter
@                 # literal
(                 # start group 2: whole domain
(?:[a-z0-9-]+\.)* # optional subdomain: don't capture
(                 #start group 3: domain
[a-z0-9_-]+       # the last word
\.                # the dot
([a-z]{2,})       # capture TLD to group 4
)                 # end group 3: domain
)                 # end group 2: whole domain
$                 # assert end of string
~";
"; ?>
以下是输出:


啊,这是因为我需要用户名至少为6个字符。很抱歉,我忘了在我的问题中包括这一点。是的,我对这一点很熟悉,但我不想处理函数调用的开销,因为我可能要处理大量的电子邮件地址,这将减慢执行速度。很好地完成了zx81-这正是我想要的。A和独角兽合作得很好thing@n00p很荣幸,感谢您的友好反馈。:)
<?php
$emails = array("username@domain.com",
           "username@us.domain.com",
           "username@au.domain.com",
           "username@us.au.domain.com");

$regex = "~(?ix) # case-insensitive, free-spacing
^                # assert head of string
([a-z0-9_-]{6,24})    # capture username to Group 1
(?<=[0-9a-z])     # assert that the previous character was a digit or letter
@                 # literal
(                 # start group 2: whole domain
(?:[a-z0-9-]+\.)* # optional subdomain: don't capture
(                 #start group 3: domain
[a-z0-9_-]+       # the last word
\.                # the dot
([a-z]{2,})       # capture TLD to group 4
)                 # end group 3: domain
)                 # end group 2: whole domain
$                 # assert end of string
~";

echo "<pre>";
foreach($emails as $email) {
    if(preg_match($regex,$email,$match)) print_r($match);
}
echo "</pre>";
?>
Array
(
    [0] => username@domain.com
    [1] => username
    [2] => domain.com
    [3] => domain.com
    [4] => com
)
Array
(
    [0] => username@us.domain.com
    [1] => username
    [2] => us.domain.com
    [3] => domain.com
    [4] => com
)
Array
(
    [0] => username@au.domain.com
    [1] => username
    [2] => au.domain.com
    [3] => domain.com
    [4] => com
)
Array
(
    [0] => username@us.au.domain.com
    [1] => username
    [2] => us.au.domain.com
    [3] => domain.com
    [4] => com
)