2011-08-12 50 views
1

有人可以幫助我在PHP中創建一個正則表達式解析出Akamai訪問日誌中的不同字段。下面的第一行指定了字段名稱。謝謝!Regex幫助與Akamai訪問日誌 - PHP

#Fields: date time cs-ip cs-method cs-uri sc-status sc-bytes time-taken cs(Referer) cs(User-Agent) cs(Cookie) x-custom 
2011-08-08 23:59:52 63.555.254.85 GET /somedomain/images/banner_320x50.jpg 200 10801 0 "http://somerefered.com" "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8G4" "-" "-" 

回答

1

下面是一個簡單的小測試程序,我只是寫:

<?php 
// Fields: date time cs-ip cs-method cs-uri sc-status sc-bytes time-taken cs(Referer) cs(User-Agent) cs(Cookie) x-custom 
$logLine = '2011-08-08 23:59:52 63.555.254.85 GET /somedomain/images/banner_320x50.jpg 200 10801 0 "http://somerefered.com" "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8G4" "-" "-"'; 
$regex = '/^(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})\s+(\d{1,3}(?:\.\d{1,3}){3})\s+([A-Za-z]+)\s+(\S+)\s+(\d{3})\s+(\d+)\s+(\d+)\s+"([^"]*)"\s+"([^"]*)"\s+"([^"]*)"\s+"([^"]*)"$/'; 

$matches = array(); 
if (preg_match($regex, $logLine, $matches)) { 
    $logParts = array(
     'date' => $matches[1], 
     'time' => $matches[2], 
     'cs-ip' => $matches[3], 
     'cs-method' => $matches[4], 
     'cs-uri' => $matches[5], 
     'sc-status' => $matches[6], 
     'sc-bytes' => $matches[7], 
     'time-taken' => $matches[8], 
     'cs(Referer)' => $matches[9], 
     'cs(User-Agent)' => $matches[10], 
     'cs(Cookie)' => $matches[11], 
     'x-custom' => $matches[12] 
    ); 
    print_r($logParts); 
} 
?> 

此輸出:

Array 
(
    [date] => 2011-08-08 
    [time] => 23:59:52 
    [cs-ip] => 63.555.254.85 
    [cs-method] => GET 
    [cs-uri] => /somedomain/images/banner_320x50.jpg 
    [sc-status] => 200 
    [sc-bytes] => 10801 
    [time-taken] => 0 
    [cs(Referer)] => http://somerefered.com 
    [cs(User-Agent)] => Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8G4 
    [cs(Cookie)] => - 
    [x-custom] => - 
) 
+1

工程就像一個魅力! – VinnyD

1

看起來像字段是製表符分隔。如果是這樣,你不需要正則表達式,但只可以做:

$fieldnames = array('date', 'time', 'cs-ip', 'cs-method', 'cs-uri', 'sc-status', 'sc-bytes', 'time-taken', 'cs(Referer)', 'cs(User-Agent)', 'cs(Cookie)', 'x-custom'); 

$parsed = array(); 
foreach($lines as $line) { 
    $fields = explode("\t", $line); 
    foreach($fields as $index => $field) { 
     $tmp = array(); 
     $tmp[$fieldnames[$index]] = $field; 
    } 

    $parsed[] = $tmp; 
} 

現在你將有一個很好的陣列與字段名作爲鍵。

+0

的OP要求基於正則表達式的解決方案。此外,如果其中一個引用字段包含製表符,則會中斷。 – Asaph

+0

@Asaph:你說的正確,OP要求正則表達式。然而,考慮到你的代表,你也會知道,這裏的許多人會在不需要/不需要的時候要求一個正則表達式。在引用字段中也不會有任何製表符。雖然如果文件不是製表符分隔的話,我會羞於低頭,刪除我的答案,爲浪費大家的時間而打開另一個啤酒道歉:-) – PeeHaa

+0

確實,regexes經常被濫用。這種情況是臨界的。我可以去任何一個方面。日誌行看起來是製表符分隔的。我不相信引用的字段永遠不會包含製表符。它們中的很多都是由客戶端通過HTTP頭提供的。如果某人用帶有選項卡的用戶代理字符串向Web服務器發出請求,該怎麼辦?什麼將出現在日誌文件中? – Asaph