2010-02-08 6 views
6

Sto cercando di dividere questa stringa in PHP:come analizzare i log di Apache utilizzando un'espressione regolare in PHP

11.11.11.11 - - [25/Jan/2000:14:00:01 +0100] "GET /1986.js HTTP/1.1" 200 932 "http://domain.com/index.html" "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6" 

Come può dividere questo in IP, data, metodo HTTP, domain-name e browser?

+1

Questa è una versione peggiore di questa domanda, che va in pieno l'analisi: http://stackoverflow.com/questions/ 7603017/parse-apache-log-in-php-using-preg-match – ftrotter

risposta

12

Questo formato di registro sembra essere il Apache’s combined log format. Prova questa espressione regolare:

/^(\S+) \S+ \S+ \[([^\]]+)\] "([A-Z]+)[^"]*" \d+ \d+ "[^"]*" "([^"]*)"$/m 

I gruppi corrispondenti sono i seguenti:

  1. IP remoto indirizzo
  2. richiesta data
  3. metodo di richiesta HTTP
  4. User-Agent valore

Ma il dominio non è elencato il ri. La seconda stringa citata è il valore Referer.

+0

Devo anche dividerli – streetparade

+1

@streetparade: usa 'preg_match_all' e ottieni tutte le corrispondenze:' preg_match_all ('...', $ str, $ matches) ' – Gumbo

+0

beh questa espressione regolare non viene compilata ... manca una parentesi rotonda;) –

4

È consigliabile consultare un'esercitazione con espressioni regolari. Ma ecco la risposta:

if (preg_match('/^(\S+) \S+ \S+ \[(.*?)\] "(\S+).*?" \d+ \d+ "(.*?)" "(.*?)"/', $line, $m)) { 
    $ip = $m[1]; 
    $date = $m[2]; 
    $method = $m[3]; 
    $referer = $m[4]; 
    $browser = $m[5]; 
} 

Fare attenzione, non è il nome di dominio nel registro ma il riferimento HTTP.

4

Ecco alcuni Perl, non PHP, ma la regex da utilizzare è la stessa. Questa regex funziona per analizzare tutto ciò che ho visto; i clienti possono inviare alcune bizzarre richieste:

my ($ip, $date, $method, $url, $protocol, $alt_url, $code, $bytes, 
     $referrer, $ua) = (m/ 
    ^(\S+)\s     # IP 
    \S+\s+      # remote logname 
    (?:\S+\s+)+     # remote user 
    \[([^]]+)\]\s    # date 
    "(\S*)\s?     # method 
    (?:((?:[^"]*(?:\\")?)*)\s # URL 
    ([^"]*)"\s|     # protocol 
    ((?:[^"]*(?:\\")?)*)"\s) # or, possibly URL with no protocol 
    (\S+)\s      # status code 
    (\S+)\s      # bytes 
    "((?:[^"]*(?:\\")?)*)"\s # referrer 
    "(.*)"$      # user agent 
/x); 
die "Couldn't match $_" unless $ip; 
$alt_url ||= ''; 
$url ||= $alt_url; 
1
// # Parses the NCSA Combined Log Format lines: 
$pattern = '/^([^ ]+) ([^ ]+) ([^ ]+) (\[[^\]]+\]) "(.*) (.*) (.*)" ([0-9\-]+) ([0-9\-]+) "(.*)" "(.*)"$/'; 

Usage:

if (preg_match($pattern,$yourstuff,$matches)) { 

    //# puts each part of the match in a named variable 

    list($whole_match, $remote_host, $logname, $user, $date_time, $method, $request, $protocol, $status, $bytes, $referer, $user_agent) = $matches; 

} 
Problemi correlati