2009-11-25 69 views
19

我的文字的字符串看起来像这样的用户名:使用正则表达式来提取电子邮件地址

[email protected] (John Doe) 

我需要得到公正的@,并没有别的之前的部分。如果有任何问题,文本来自简单的XML对象。

我的代码看起来是这样的:

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

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

有时用户名可能有号码或@符号前面的下划线,这哪里是正则表达式停止它似乎。

+0

你的正则表达式的外捕获组'()'和内部非捕获组'(:)'。考虑到您想要捕捉内部内容,内部非捕获组可能是不必要的。 '[a-z]'表示捕获一个小写字母。 '[a-z] +'表示捕获一个或多个小写字母。因此,有效地表达意味着捕获长度为2个或更多个小写字母的任何内容。如果要在表达式的前面放置一个'^',它将确保匹配只从文本的_beginning_开始。 – 2009-11-25 17:04:45

+0

我恐惧不会很好玩。您可能想要测试的一些示例字符串:'“John Doe”@ example.com(John Doe)','“(>'.')>"@example.com(John Doe)','foo @ [192.168。 2.1](John Doe)','^.^@example.com(John Doe)','"[email protected]@c"@example.com(John Doe)“'是的,这些都是有效的电子邮件地址:-) – Joey 2009-11-25 17:06:18

+0

@Johannes:'"[email protected]@c"@example.com(John Doe)'是真的允许吗?这真的让事情变得复杂...... – Welbog 2009-11-25 17:08:05

回答

59

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

([^@]+) 

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


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

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

$parts = explode("@", "[email protected]"); 
$username = $parts[0]; 

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


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

+0

取决于你的正则表达式可以得到多么强烈,我个人喜欢爆炸的功能,适合你的要求 – 2009-11-25 17:06:47

+2

什么是电子邮件地址'“a @ b”@ example.com'? – Joey 2009-11-25 17:07:26

+1

这个乐趣永远不会以电子邮件地址中的源路由结束:http://www.remote.org/jochen/mail/info/address.html – 2009-11-25 17:09:08

2

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

2

去您可以通过使用mailparse_rfc822_parse_addresses来解析地址,只提取地址规范没有任何显示的名字开始。然后,您可以使用正则表达式(.*)@@之前提取零件。

2

@OP,如果你只想得到@之前的所有东西,只需使用字符串/数组方法即可。不需要复杂的正则表达式。爆炸的“@”,然后取出的最后一个元素是域部分

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

输出

$ php test.php 
"[email protected]@doe" 
3

也许该变型比爆炸()慢一点,但它需要仅仅一个字符串:

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

使用这样的事情:

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

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

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

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

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

source

0

基本例如:

$email = "[email protected]"; 
    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 ; 
0

我的建议:

$email = '[email protected]'; 
$username = substr($email, 0, strpos($email, '@')); 

// Output (in $username): johndoe 
相关问题