30

我的文本字符串如下所示:

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];
}

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

4

13 回答 13

94

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

([^@]+)

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


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

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

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

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


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

于 2009-11-25T17:01:27.443 回答
7

@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"
于 2009-11-26T00:47:51.163 回答
6

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

$name = preg_replace('/@.*?$/', '', $email);
于 2011-06-13T17:00:55.900 回答
4
<?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
?>

来源

于 2015-06-29T12:05:17.203 回答
4

我用preg_replace

$email_username = preg_replace('/@.*/', '', $_POST['email']);
于 2017-10-15T13:30:14.277 回答
3

我的建议:

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

// Output (in $username): johndoe
于 2017-12-17T02:36:50.203 回答
2

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

于 2009-11-25T17:30:46.937 回答
2

您可以首先使用mailparse_rfc822_parse_addresses解析地址并仅提取地址规范而无需任何显示名称。然后,您可以@使用 regexp提取之前的部分(.*)@

于 2009-11-25T18:22:30.327 回答
1

使用这样的东西:

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

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

."@": 这样做是为了避免 list 命令出现严重错误,并确保explode根据需要产生至少两个变量。

于 2013-04-05T14:11:19.587 回答
1

如果有人仍在寻找 2020 年 ..here 的正则表达式可以选择“@”之前的文本

^(\S+)(?=@)
于 2020-06-27T18:59:35.990 回答
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 ;
于 2017-07-14T16:36:39.957 回答
0

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

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

输出:

沙阿

于 2019-05-03T02:28:11.703 回答
-1

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

if ($c = preg_match_all ('^([\w\.\+\-]*)', $authorpre, $matches))
于 2019-08-14T16:38:01.443 回答