使用正则表达式从电子邮件地址中提取用户名

时间:2009-11-25 16:58:38

标签: php regex preg-match

我的文字字符串如下:

johndoe@domain.com (John Doe)

我需要在@之前获得部分,而不是其他任何东西。如果重要的话,文本来自一个简单的XML对象。

我的代码如下:

$authorpre = $key->{"author"};
$re1 = '((?:[a-z][a-z]+))';

if ($c = preg_match_all ("/".$re1."/is", $authorpre, $matches))
{
    $author = $matches[1][0];
}

有时用户名可能在@符号之前有数字或下划线,这正是正则表达式停止的地方。

13 个答案:

答案 0 :(得分:78)

将匹配并捕获任何字符的正则表达式,直到它到达@字符:

([^@]+)

这似乎就是你所需要的。它将处理电子邮件地址上的各种怪异变化。


我不确定为什么Ben James删除了他的答案,因为我觉得它比我的好。我将在这里发布(除非他取消回答):

  

为什么使用正则表达式而不是字符串函数?

$parts = explode("@", "johndoe@domain.com");
$username = $parts[0];

在这种情况下你根本不需要正则表达式。我认为使用explode是一个更好的选择,就个人而言。


正如Johannes Rössel在评论中指出的那样,电子邮件地址解析相当复杂。如果您想100%确定您能够处理任何技术上有效的电子邮件地址,那么您将不得不编写一个能够正确处理报价的例程,因为我的答案中列出的两个解决方案都会窒息地址如"a@b"@example.com。可能有一个库为您处理这种解析,但我不知道它。

答案 1 :(得分:6)

@OP,如果您只想在@之前获取所有内容,只需使用字符串/数组方法。不需要复杂的正则表达式。爆炸“@”,然后删除作为域部分的最后一个元素

$str = '"peter@john@doe"@domain.com (John Doe)';
$s = explode("@",$str);
array_pop($s); #remove last element.
$s = implode("@",$s);
print $s;

输出

$ php test.php
"peter@john@doe"

答案 2 :(得分:5)

也许这个变体比explode()慢一点,但它只需要一个字符串:

$name = preg_replace('/@.*?$/', '', $email);

答案 3 :(得分:2)

我会选择$author = str_replace(strrchr($authorpre, '@'), '', $authorpre);

答案 4 :(得分:2)

您可以先使用mailparse_rfc822_parse_addresses解析地址,然后只提取地址规范而不显示任何显示名称。然后,您可以使用正则表达式@提取(.*)@之前的部分。

答案 5 :(得分:2)

<?php
$email  = 'name@example.com';
$domain = strstr($email, '@');
echo $domain; // prints @example.com

$user = strstr($email, '@', true); // As of PHP 5.3.0
echo $user; // prints name
?>

source

答案 6 :(得分:1)

使用类似的东西:

list($username, $domain) = explode('@', $email . "@"); // ."@" is a trick: look note below

使用此解决方案,您已经在一行中填充了两个带有电子邮件地址部分的变量。

."@":这是为了避免使用list命令发生短暂的严重错误,并确保explode将根据需要生成至少两个变量。

答案 7 :(得分:1)

我使用了preg_replace

$email_username = preg_replace('/@.*/', '', $_POST['email']);

答案 8 :(得分:1)

以防有人在2020年看书..这是可以在'@'之前选择文本的正则表达式。

^(\S+)(?=@)

答案 9 :(得分:0)

基本示例:

    $email = "linuxUser@IsGrand.com";
    if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
        list($user, $domain) = explode('@', trim($email) . "@");
    } else {
        echo "Unable to get account info ....";
    }

复杂的例子: 这样填充名字和姓氏字段:

1) valid email ?  if yes get the two parts  user and domain.
2) else set to something default etc.
3) use the email address if we don't have a decoded value.

代码:

    if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
        list($fname, $lname) = explode('@', trim($email) . "@");
    } else {
        $fname = "Xdefault";
        $lname = "Ydefault";
    }

    $fname = (!empty($decoded['firstname'][0]))  ? $decoded['firstname'][0] : $fname ;
    $lname = (!empty($decoded['lastname'][0]))  ? $decoded['lastname'][0] : $lname ;

答案 10 :(得分:0)

我的建议:

$email = 'johndoe@domain.com';
$username = substr($email, 0, strpos($email, '@'));

// Output (in $username): johndoe

答案 11 :(得分:0)

我还想在此建议一个非正则表达式解决方案,因为它在大多数情况下可能有用:

strstr('n.shah@xyz.co', '@', true)

输出:

  

n.shah

答案 12 :(得分:0)

我已经测试了下面的模式,它给了我地址的开始部分,包括句点,加号和破折号。

if ($c = preg_match_all ('^([\w\.\+\-]*)', $authorpre, $matches))