2010-02-08 13 views
6

Estoy tratando de dividir esta cadena en PHP:cómo analizar los registros de Apache utilizando una expresión regular en 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" 

Cómo puede dividir esto en IP, la fecha, el método HTTP, de nombre de dominio y el navegador?

+1

Esta es una versión peor de esta pregunta, que entra en plena análisis: http://stackoverflow.com/questions/ 7603017/parse-apache-log-in-php-using-preg-match – ftrotter

Respuesta

12

Este formato de registro parece ser el Apache’s combined log format. Prueba esta expresión regular:

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

Los grupos relacionados son los siguientes:

  1. IP remota Dirección
  2. Fecha de solicitud de
  3. solicitud de método HTTP
  4. User-Agent valor

Pero el dominio no está en la lista re. La segunda cadena entre comillas es el valor Referer.

+0

También necesito dividirlos – streetparade

+1

@streetparade: Use 'preg_match_all' y obtendrá todas las coincidencias:' preg_match_all ('...', $ str, $ matches) ' – Gumbo

+0

bien esta expresión regular no se compila ... hay falta una ronda de corchetes;) –

4

Debe consultar un tutorial de expresiones regulares. Pero aquí está la respuesta:

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]; 
} 

Tenga cuidado, no es el nombre del dominio en el registro sino el referer del HTTP.

4

Aquí hay algunos Perl, no PHP, pero la expresión regular para usar es la misma. Esta expresión regular funciona para analizar todo lo que he visto; Los clientes pueden enviar algunas peticiones extrañas:

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\-]+) "(.*)" "(.*)"$/'; 

Uso:

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; 

} 
Cuestiones relacionadas