Reputation: 1321
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.
Upvotes: 0
Views: 296
Reputation: 1963
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";
)
)
)
Upvotes: 1
Reputation: 50187
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.
Upvotes: 0