我正在尝试使用最简单的正则表达式验证电子邮件地址 - 不是 - RFC‑822–compliant regex
还需要捕获用户名 - 子域名(如果有的话) - 域名和 - 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
并且正则表达式应该验证它们并捕获所有组。
所以,我想知道正则表达式是否正确或者还有什么我需要考虑的吗?
答案 0 :(得分:2)
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
~";
这将捕获组1的用户名,整个域到组2,域到组3,以及TLD到组4。
您将看到的一个小变化是我在角色类中没有转义-
和.
,因为没有必要这样做。我没有用[a-z0-9_]
替换\w
表达式,因为如果您切换到unicode或其他语言环境,我们可能会得到令人惊讶的结果。
以下是使用中的全部内容:
<?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
)
答案 1 :(得分:1)
最有可能的是,您最好使用parse_url来获取零件,然后针对不同的零件进行任何类型的验证
答案 2 :(得分:0)
我已经尝试了一段时间,但我仍然没有得到最合适的结果,但这是我到目前为止最接近的结果:
^([a-z0-9_\-\.]{6,24})(?<=[0-9a-z])@((?:[a-z0-9][-\w]*[a-z0-9]*\.)+([a-z]{2,}))$
这将捕获用户名,TLD后缀和整个域,以及验证包含或不包含子域的电子邮件。但我仍然无法提取域名。我想我现在可以忍受。
对于诸如username@domain.com之类的电子邮件,它将验证并捕获用户名,domain.com和com以及其他电子邮件,例如username@au.domain.com,它将验证并捕获用户名,au.domain.com和com
这不完全不是我想要的,可能会有人会提出更好的解决方案并在此发布。