在PHP中从电子邮件地址获取用户名

20

在 PHP 中,我有一个像这样的字符串:

$string = "user@domain.com";

我怎样仅通过电子邮件地址获取“用户”?有没有简单的方法可以获取 @ 前的值?


5
注意:电子邮件地址可能包含多个“@”符号...! - deceze
2
您可以通过strstr()函数查看此示例:http://php.net/manual/en/function.strstr.php#example-4852 - Arno
以上解决方案返回的结果是用户名,而不是域名。 我找到了一个解决方案,可以从电子邮件中获取域名,无论它包含多少个“@”,它总是会给出正确的域名。 function getDomain($email) { $brokenEmail = explode('@', $email);$brokenEmailCount = count($brokenEmail); return $brokenEmail[$brokenEmailCount - 1]; } - Jaskaran Singh
1
@John - FYI,在我的“真实场景”中,我有两个每天都在使用的带有两个“@”符号的电子邮件地址 - 实际上,它们是我的主要电子邮件地址。我已经使用它们至少20年了。我猜我从来没有登录过你处理电子邮件的任何地方 - 但它们确实存在并且被广泛使用! - Apps-n-Add-Ons
1
@CFPSupport 我们这样来说吧:您可以轻松地在任何工具、购物车、网站中禁止任何此类电子邮件地址,而这种决定的经济影响是不可感知的。这就像排除对Windows 3.11的支持一样。 - John
显示剩余5条评论
6个回答

33
假设电子邮件地址有效,这种文本方法应该可以起作用:
$prefix = substr($email, 0, strrpos($email, '@'));

它提取从开头到(但不包括)最后一个 @ 的出现位置之前的所有内容。使用最后一个出现位置是因为这个电子邮件地址是有效的:

"foo\@bar"@iana.org
如果您尚未验证字符串,请使用过滤函数进行建议:
if (($email = filter_var($email, FILTER_VALIDATE_EMAIL)) !== false) {
    // okay, should be valid now
}

3
@jpro 我觉得问题的标题是错误的 :) - Ja͢ck

5
请尝试以下操作:
$string = "user@domain.com";

$explode = explode("@",$string);

array_pop($explode);

$newstring = join('@', $explode);

echo $newstring;

对于多个“@”符号进行了修改。


这不符合RFC标准,如果一个地址包含多个“@”可能会失败!是的,这是可能的(虽然在实践中并不常见)! - deceze
1
这将无法处理地址 "Abc\@def"@iana.org 和许多其他地址。 - PeeHaa
str_getcsv()函数使用@作为分隔符,但是允许在邮箱中使用引号可能是另一种解决方案。代码示例:$explode = str_getcsv($string, '@','"'); - Mark Baker
编辑了多个@符号,虽然这可能不是最好的方法。 - Ben Fortune
可以使用array_pop来删除数组的最后一个元素,然后使用@将数组implode以将其返回为字符串。这可能有助于具有多个@符号的地址。 - user849001
与使用简单的 strrpos()substr() 相比,使用数组会很沉重。 - Ja͢ck

3

您可以使用

$user = implode('@', explode('@', $email, -1));

或者

$user = substr($email, 0, strrpos($mail, '@'));

这个未解释的答案的第一个片段可能对所有有效的电子邮件地址都不可靠。如果电子邮件地址的“用户名”部分被包含在双引号中,则可能包含@。https://dev59.com/93I-5IYBdhLWcg3wBjjk:~:text=%22very.unusual.%40.unusual.com%22%40example.com - mickmackusa

2

在PHP手册中的strpos()函数入口页有一个很好的例子:http://php.net/manual/en/function.strstr.php#117530

PHP为你提供了方便。当处理电子邮件地址的域名部分时,只需将strstr()的返回值传递给substr(),并从第1个字符开始:

substr(strstr($haystack, '@'), 1);


这实际上是一个仅包含链接的答案。如果该链接失效,这个答案对研究人员的价值就很小了。 - mickmackusa
这个返回域名而不是用户,就像用户请求的那样。 - dAm2K
如果地址包含多个“@”,则此方法将无法正常工作。 - Steve
并非所有有效的电子邮件地址都是如此。如果电子邮件地址的“用户名”部分被包含在双引号内,则可能包含@。https://dev59.com/93I-5IYBdhLWcg3wBjjk:~:text=%22very.unusual.%40.unusual.com%22%40example.com - mickmackusa

1

您可以使用:

strstr($email, '@', true);

1
并非所有有效的电子邮件地址都是如此。如果电子邮件地址的“用户名”部分被双引号包含,它可能会包含@。https://dev59.com/93I-5IYBdhLWcg3wBjjk:~:text=%22very.unusual.%40.unusual.com%22%40example.com 本页面上的其他答案适当地处理了这种边缘情况。 - mickmackusa
strtok($email, '@') 也可以用于99.99999999999%的电子邮件。 - Semra

0
在最简单的形式下(假设只有一个“@”符号),您可以按照@Ben Fortune的答案(使用explode()函数)进行操作。
否则,请尝试以下方法:
$email1 = "foo@example.com";
$email2 = "b\@r@example.com";

preg_match_all ("/^(.+)@[^@]+$/", $email1, $e1);
preg_match_all ("/^(.+)@[^@]+$/", $email2, $e2);

echo "Emails: {$e1[1][0]} and {$e2[1][0]}\n";
// Result: Emails: foo and b\@r

这对于多个@也适用,只是正则表达式在这里不是正确的工具 :) - Ja͢ck
是的,在这里使用正则表达式可能有些过度了。你的答案更简单。我不记得有函数strrpos()存在。 - Sutandiono

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接