Karmaşık bir hedef dize ile PHP Regex sorun

2 Cevap php

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

Burada örnek çıktı

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

Sorun i xx.xx.xx.xx ... {.. kira sonra ip adresleri ile endeksli bir diziye bütün tablo atamak istiyoruz ve bir Orada yinelenen anahtarlar olacak ama değerler yüzden bu çözmek için gereken farklı olacak ...

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.

2 Cevap

Ben bunu düşünüyorum:

<?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);
?>

Örnek Çıktı:

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";
                )

        )

)

Sadece de bu ayrıştırmak. Satır satır okuyun ve değişkenler mevcut durumu korumak. Eğer lease ... ile bir çizgi vurdu ve set lease fıkra, $inLease true ve dinlenme işlemek değil olduğunuzda lease geçerli parametre olarak çizgiler böylece kapanış ayracı }, ve vurmak kadar.

Düzenli ifadeler, bu durumda size yardımcı olabilir, ama bu sadece basit çizgi-by-line ayrıştırma yapmak zor olmayacaktır. Veri formatı nasıl statik göz önüne alındığında, düzenli ifadeler sadece bu için abartılı olur.