2012-09-20 16 views
0

我正在設置一個PHP腳本,該腳本將從維護幫助桌面向其發送電子郵件。這些電子郵件是從我們客戶公司使用的網頁表單發送的,我無法控制這些網頁。這些電子郵件格式標準化,但包含一個列表,其中包含從Web表單提供的標籤。我想使用正則表達式來拆分這個列表,並將標籤和值放入一個數組中,我可以將它們輸入到我自己的數據庫中。我在旅途中得到了一個可行的解決方案,但我在正則表達式方面很新,我確信有一個更好/更有效的方法來做到這一點。使用preg_match_all從文本體中分離標籤和值的列表

,我可以收到電子郵件的一個例子:

Dear *MY COMPANY*, 

A new job has been raised, please see details below. 
If you are unable to action this job request, please notify the Maintenance Help Desk on xxx-xxxx as soon as possible. 

    Job Type: Man In Van 
    Job Code: 1462399 
    Due Date: 27/09/2012 07:21:10 
    Response Time: Man In Van 
    Pub Number: 234 
    Pub Name: pub name, location 
    Pub Address: 123 somewhere, some place XX1 7XX 
    Pub Post Code: XX1 7XX 
    Pub Telephone Number: xxx xxxx 
    Placed By: Ben 
    Date/time placed: 20/09/2012 07:21:10 
    Trade Type: Man In Van 
    Description: List of jobs emailed by Chris, carried out by Martin Baker. No callout on system currently, although jobs already completed, just need signing off. 


    For any queries, please either contact the pub directly, telephone the Maintenance Help Desk on xxx-xxxx or reply to this e-mail. 

Many Thanks 
*CLIENT COMPANY* 

有周圍更多的樣板,顯然電子郵件標題等,但你的想法。每封電子郵件只會包含一個列表,並且標籤將保持不變,儘管我希望將來能夠證明它,所以如果他們添加新字段,我不需要更改我的代碼。我想以與陣列如落得:

$job['Job Type'] = Man in van 
$job['Job Code'] = 1462399 
... 
$job['Description'] = List of all jobs emailed ... just need signing off. 

雖然我可以確信,該格式不會改變,每一種形式是用戶輸入並且因此可以是不可預知的,尤其是本說明書中,其可以含有線休息。

這是我使用的那一刻代碼:

// Rip out the job details from the email 
preg_match_all('/job type\:.*description\:.*\s{3}F/is', $the_email, $jobs); 

    for each job returned (should always be one but hey) 
    foreach($jobs[0] as $job_details) { 

// Get the variables from the job description 
    preg_match_all('/(\w[^\:]*)\: ([\w\d][^\*]+)/i', $job_details, $the_vars); 

} 

    // For each row returned, put into an array with the first group as the key and the second as the value 
for ($i=0; $i<count($the_vars[0]); $i++) { 

    $arr[$the_vars[1][$i]] = $the_vars[2][$i]; 

} 

它的工作原理,但它是醜陋,我敢肯定有一個更好的辦法。我遇到的主要問題是描述部分,因爲我不能簡單地搜索':'後面的文本直到換行,因爲描述本身可能包含換行符。

任何意見將不勝感激!

+0

我會使用正則表達式模式的白名單陣列特異性匹配每個'FIELD_NAME:'標籤在電子郵件中。該正則表達式應該利用^符號來匹配字符串中的第一個字符,並確保您的匹配僅在新行的開頭,從而避免值中的誤報。 – ficuscr

+0

我明白你的意思,但我想添加選項,讓他們添加更多的領域在他們身邊和正則表達式來捕獲新的標籤/值沒有任何改變的代碼。雖然我可能最終會實施這樣的事情,但你指出它會更安全' – Gruffy

回答

0

仍然不是世界上最漂亮的東西,但它應該工作得很好!

preg_match_all('/\s{3}[ ]*([^:]+): ([^\n]+)/', $subject, $matches); 
$job = array_combine($matches[1], $matches[2]); 

preg_match_all('/Description\: (.*)\s{3}For any queries/is', $subject, $match); 
$job['Description'] = trim($match[1][0]); 

第一preg_match_all做你所說的話並沒有真正的工作,只是抓住所有的空格,冒號和新行的字段。

第二個替換潛在錯誤說明密鑰的第一個中填充

+0

我喜歡這個想法,明天我會試試看,並嘗試使用其他一些電子郵件。我能看到的唯一問題是如果他們添加了另一個類似於描述的「文本」字段,但這不太可能比另一個標準化字段。謝謝! – Gruffy

+0

也感謝您指出array_combine - 我從來沒有打過電話來使用它:) – Gruffy