2011-07-07 50 views
1

我想用preg_match_all解析電子郵件地址列表(如TO標頭中的那個)以獲取用戶名(如果存在)和電子郵件。類似於Pear中的mailparse_rfc822_parse_addresses或Mail_RFC822 :: parseAddressList(),但是使用普通的PHP。解析TO標頭中的符合RFC 822的地址

輸入:

"DOE, John \(ACME\)" <[email protected]>, "DOE, Jane" <[email protected]> 

輸出:

array(
    array(
     'name' => 'DOE, John (ACME)', 
     'email' => '[email protected]' 
    ), 
    array(
     'name' => 'DOE, Jane', 
     'email' => '[email protected]' 
    ) 
) 

不需要支持奇怪的電子郵件格式(/[a-z0-9._%-][email protected][a -z0-9 .-] +。[az] {2,4} /我的電子郵件部分是確定的)。

我不能使用爆炸,因爲逗號可以出現在名稱中。 str_getcsv不起作用,因爲我可以有:

DOE, John \(ACME\) <[email protected]> 

作爲輸入。

更新:

就目前而言,我有這樣的:

public static function parseAddressList($addressList) 
{ 
    $pattern = '/^(?:"?([^<"]+)"?\s)?<?([^>][email protected][^>]+)>?$/'; 
    if (preg_match($pattern, $addressList, $matches)) { 
     return array(
      array(
       'name' => stripcslashes($matches[1]), 
       'email' => $matches[2] 
      ) 
     ); 
    } else { 
     $parts = str_getcsv($addressList); 
     $result = array(); 
     foreach($parts as $part) { 
      if (preg_match($pattern, $part, $matches)) { 
       $result[] = array(
        'name' => stripcslashes($matches[1]), 
        'email' => $matches[2] 
       ); 
      } 
     } 
     return $result; 
    } 
} 

,但它失敗的:

"DOE, \"John\"" <[email protected]> 

我需要測試後面引用\ 「但我不記得如何做到這一點。

回答

0

我不知道W在所述RFC,但如果格式始終爲您呈現,然後你可以嘗試這樣的:

preg_match_all("/\"([^\"]*)\"\\s+<([^<>]*)>/", $string, $matches); 
print_r($matches); 
+0

不起作用,因爲雙引號不是強制性的。但是,無論如何,謝謝。 – Maxence

2

最後我做到了:

public static function parseAddressList($addressList) 
{ 
    $pattern = '/^(?:"?((?:[^"\\\\]|\\\\.)+)"?\s)?<?([a-z0-9._%-][email protected][a-z0-9.-]+\\.[a-z]{2,4})>?$/i'; 
    if (($addressList[0] != '<') and preg_match($pattern, $addressList, $matches)) { 
     return array(
      array(
       'name' => stripcslashes($matches[1]), 
       'email' => $matches[2] 
      ) 
     ); 
    } else { 
     $parts = str_getcsv($addressList); 
     $result = array(); 
     foreach($parts as $part) { 
      if (preg_match($pattern, $part, $matches)) { 
       $item = array(); 
       if ($matches[1] != '') $item['name'] = stripcslashes($matches[1]); 
       $item['email'] = $matches[2]; 
       $result[] = $item; 
      } 
     } 
     return $result; 
    } 
} 

但我不知道它適用於所有的情況下, 。

+0

這個正則表達式給我帶來了一些問題,如果電子郵件地址有一個 - 在@之前,這個固定爲我(即逃避 - 在正則表達式) '$ pattern ='/ ^(?:「? ((?:[^ 「\\\\] | \\\\)+)」????\ S)<([A-Z0-9 ._%\ - +] + @ [A-z0- 9] \ - ] + \\。[az] {2,10})>?$/i';' – strikernl

+0

也會失敗,並且沒有名稱部分的普通舊電子郵件地址...需要'trim() 「part」 'Bob <[email protected]>,notparsed @ sad.com' 每個'$ part'都需要修剪,因爲領先的空間 –