2009-11-25 178 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 
相關問題