tags:

views:

97

answers:

2

Hi,

i need to parse dhcp leases table with php regex. but the thing is it contains different characters used in regex too.

here is sample output

lease 172.17.2.3 {
  starts 4 2009/07/16 11:54:39;
  ends 4 2009/07/16 12:54:39;
  cltt 4 2009/07/16 11:54:39;
  binding state active;
  next binding state free;
  hardware ethernet 00:50:56:c0:00:01;
  uid "\001\000PV\300\000\001";
  client-hostname "Yasin-PC";
}
lease 172.17.2.3 {
  starts 4 2009/07/16 12:24:39;
  ends 4 2009/07/16 13:24:39;
  cltt 4 2009/07/16 12:24:39;
  binding state active;
  next binding state free;
  hardware ethernet 00:50:56:c0:00:01;
  uid "\001\000PV\300\000\001";
  client-hostname "Yasin-PC";
}
lease 172.17.2.3 {
  starts 4 2009/07/16 12:54:39;
  ends 4 2009/07/16 13:54:39;
  cltt 4 2009/07/16 12:54:39;
  binding state active;
  next binding state free;
  hardware ethernet 00:50:56:c0:00:01;
  uid "\001\000PV\300\000\001";
  client-hostname "Yasin-PC";
}

problem is i want to assign whole table into an array indexed with ip addresses after lease ..XX.XX.XX.XX {... & there will be duplicate keys but values will be different so i need to solve that to...

what would you advice me to save my time to build a good regex for this ? posix or pcre or reading line by line ?

& i can not be sure about target leases table will be all in the same format. maybe some times a few more lines i expect.

A: 

You could just as well parse this. Read line by line and keep current state in variables. When you hit a line with lease ... and you're not in a lease clause, set $inLease to true and handle the rest of the lines as parameters to the current lease until you hit closing brace }, and so on.

Regular expressions could help you in this case, but it won't be harder to just do simple line-by-line parsing. Considering how static the data format is, regular expressions would just be overkill for this.

Blixt
it seems your way is better than to parse whole file. i'm trying it now. thank you for answer :)
risyasin
+1  A: 

I think you could do this:

<?php
$order_fields = array('starts', 'ends', 'cltt', 'binding state', 'next binding state', 'hardware ethernet', 'uid', 'client-hostname');
$fields_regexp = '';
foreach ($order_fields as $field)
{
    $fields_regexp .= "\s*".$field." (.*)";
}
$regexp = '/lease (\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b) \{'.$fields_regexp.'\s*\}/m';
preg_match_all($regexp, $string, $result, PREG_PATTERN_ORDER);

$arr = array();
foreach ($result[1] as $i => $match) {
    $cont = count($arr[$match]);
    $arr[$match][$cont]['raw'] = $result[0][$i];
    $arr[$match][$cont]['ip'] = $match;
    foreach ($order_fields as $pos => $field)
    {
     $arr[$match][$cont][$field] = $result[$pos + 2][$i];
    }
}
print_r($arr);
?>

Sample Output:

Array
(
    [172.17.2.3] => Array
        (
            [0] => Array
                (
                    [raw] => lease 172.17.2.3 {
  starts 4 2009/07/16 11:54:39;
  ends 4 2009/07/16 12:54:39;
  cltt 4 2009/07/16 11:54:39;
  binding state active;
  next binding state free;
  hardware ethernet 00:50:56:c0:00:01;
  uid "�PVÀ�";
  client-hostname "Yasin-PC";
}
                    [ip] => 172.17.2.3
                    [starts] => 4 2009/07/16 11:54:39;
                    [ends] => 4 2009/07/16 12:54:39;
                    [cltt] => 4 2009/07/16 11:54:39;
                    [binding state] => active;
                    [next binding state] => free;
                    [hardware ethernet] => 00:50:56:c0:00:01;
                    [uid] => "�PVÀ�";
                    [client-hostname] => "Yasin-PC";
                )

            [1] => Array
                (
                    [raw] => lease 172.17.2.3 {
  starts 4 2009/07/16 12:24:39;
  ends 4 2009/07/16 13:24:39;
  cltt 4 2009/07/16 12:24:39;
  binding state active;
  next binding state free;
  hardware ethernet 00:50:56:c0:00:01;
  uid "�PVÀ�";
  client-hostname "Yasin-PC";
}
                    [ip] => 172.17.2.3
                    [starts] => 4 2009/07/16 12:24:39;
                    [ends] => 4 2009/07/16 13:24:39;
                    [cltt] => 4 2009/07/16 12:24:39;
                    [binding state] => active;
                    [next binding state] => free;
                    [hardware ethernet] => 00:50:56:c0:00:01;
                    [uid] => "�PVÀ�";
                    [client-hostname] => "Yasin-PC";
                )

            [2] => Array
                (
                    [raw] => lease 172.17.2.3 {
  starts 4 2009/07/16 12:54:39;
  ends 4 2009/07/16 13:54:39;
  cltt 4 2009/07/16 12:54:39;
  binding state active;
  next binding state free;
  hardware ethernet 00:50:56:c0:00:01;
  uid "�PVÀ�";
  client-hostname "Yasin-PC";
}
                    [ip] => 172.17.2.3
                    [starts] => 4 2009/07/16 12:54:39;
                    [ends] => 4 2009/07/16 13:54:39;
                    [cltt] => 4 2009/07/16 12:54:39;
                    [binding state] => active;
                    [next binding state] => free;
                    [hardware ethernet] => 00:50:56:c0:00:01;
                    [uid] => "�PVÀ�";
                    [client-hostname] => "Yasin-PC";
                )

        )

)
inakiabt
thank you very much... ti works just fine :)
risyasin