Доброго времени суток уважаемый all.Возникла необходимость распарсить файл лиза dhcp.
Вид он имеет приблизительно такой:
lease 192.168.100.91 {
starts 1 2008/04/28 11:42:29;
ends 4 2008/05/01 11:42:29;
binding state active;
next binding state free;
hardware ethernet 00:1b:38:6f:67:b1;
uid "\001\000\0338og\261";
client-hostname "Marlou";
}
lease 192.168.100.163 {
starts 1 2008/04/28 19:07:36;
ends 4 2008/05/01 19:07:36;
binding state active;
next binding state free;
hardware ethernet 00:1d:60:76:32:db;
uid "\001\000\035`v2\333";
client-hostname "philka";
}Каждый из таких наборов ( lease 192.168.100.163 {...} ) нужно передать в массив, из которого потом будут извлекаться для дальнейшей обработки.
В результате поисков был сделан вот такой вот код:
<?php
$menu_string = implode( "", file( "dhcpd/dhcpd.leases" ) );
preg_match_all( '/lease.*\n.*/', $menu_string, $out );
print_r( $out );
?>Код сделан для тестов, поэтому просьба не судить строго, стажа в пхп у меня мало.
В результате работы кода я получаю на выход строку вида:
lease 192.168.100.163 {
starts 1 2008/04/28 19:07:36;Но это только часть того что нужно получить на выходе. Вообщем загвоздка в правильном написании регулярного выражения.
Документацию читал, но это мало что дало. Подскажите пожалуйста как это можно реализовать.
/^lease\s+[\d.]+\s+{[^}]+}/
^lease - слово lease с начала строки
\s - пробельныq символ
+ повторение предыдущего символа как минимум один раз
[d.] - класс символов состоящий из цифр и .
[^}] - класс символов состоящий из всех возможных, кроме }Также стоит посмотреть в мане как php будет работать с многострочными скалярами, возможно понадобится дополнительная опция.
Спасибо за ответ.Вообщем попробовал, результат есть, но как я понял в массив помещается только первый набор данных, дальше похоже проверка не идёт. Либо как написали нужна дополнительная опция.
Если есть ещё идеи, буду признателен за помощь.
Получилось таки.Убрал из регулярного выражения символ ^ из /^lease\s+[\d.]+\s+{[^}]+}/ . В результате идёт поиск по всему файлу. С чем связано не могу понять.
Возможно есть мысли с чем это связано, не хочется так и остаться без понимания того как это работает :) .
Ещё раз спасибо. В основном вопрос снят.
А я ведь предупреждал :)
Связано с отсутствием опции аналогичной m(multiline) в перле. В результате ^ срабатывает на начало скаляра, а не на каждую строчку(line) в нем. Не помню я как в пыхе выставляются m,s,i,x итд, посмотрите сами в мануале.
Нашёл я нужную опцию, если правильно понял, то конечный вид выражения такой(хотя работает что с этой опцией, что без неё):'/(?m)lease\s+[\d.]+\s+{[^}]+}/'
Если честно читал маны и видел все эти опции не раз, но чтобы собрать их именно в таком порядке...
После решения первого вопроса возникло ещё несколько :) .
Теперь нужно распарсить некоторые строки в каждом элементе массива. Например из такого вот кускаlease 192.168.100.163 {
starts 1 2008/04/28 19:07:36;
ends 4 2008/05/01 19:07:36;
binding state active;
next binding state free;
hardware ethernet 00:1d:60:76:32:db;
uid "\001\000\035`v2\333";
client-hostname "philka";
}нужно вынуть три строки, а именно:
1 lease 192.168.100.163 {
2 hardware ethernet 00:1d:60:76:32:db;
3 client-hostname "philka";при чём на выходе по каждой строке должно получиться следующее:
1 192.168.100.163
2 00:1d:60:76:32:db
3 philkaДля чего это нужно? Эти данные будут загоняться в хтмл-форму <select> после этого будут пересылаться другому скрипту на выполнение.
Вот код который допустим вынимает ип-адрес:
$dhcp_file = implode( "", file( "dhcpd/dhcpd.leases" ) );
preg_match_all( '/lease\s+[\d.]+\s+{[^}]+}/', $dhcp_file, $out_main );print ( "<select name=dhcp_ip_select>\n" );
print ( "<option value=\"-1\">\n" );
foreach ( $out_main as $out_main_lvl1 )
{
foreach ( $out_main_lvl1 as $out_main_lvl2 )
{
preg_match_all( '/lease\s+[\d.]+\s+/', $out_main_lvl2, $out_ip );
foreach ( $out_ip as $out_ip_lvl1 )
{
foreach ( $out_ip_lvl1 as $out_ip_lvl2 )
{
print ( "<option value=".$out_ip_lvl2.">".$out_ip_lvl2."\n" );
}
}
}
}
print ( "</select>\n" );Недостаток в том что на выходе получаю не только ип-адрес, но весь кусок строки вида "lease 192.168.100.163".
Если поможете правильно описать и эти куски, то буду весьма признателен :).
Первые два выражения сделал, не совсем красиво, но работает:для ип-адреса /\s+\d+\.\d+\.\d+\.\d+/
для мак-адреса /\s+[0-h][0-h]\:[0-h][0-h]\:[0-h][0-h]\:[0-h][0-h]\:[0-h][0-h]\:[0-h][0-h]/С именем хоста сложнее, не за что зацепиться, всё портит вот эта строка:
uid "\001\000\035`v2\333";
по виду похожа на:
client-hostname "philka";