» »

[any] dhcpd.leases datoteka in regularni izrazi

[any] dhcpd.leases datoteka in regularni izrazi

McAjvar ::

Imam manjsi problem. Prebrati moram in malo obdelati podatke v dhcpd.leases datoteki, in sicer dobiti zelim ven posamezne "lease" odseke in nato vsakega posebej obravnavati. Trenutno preberem celotno datoteko v spremenljivko kot string in nato s preg_match operiram na tem stringu. Izraz
lease\s*(\d\.)+\s*\{[^}]+}[\s\r\n]*
je deloval povsem v redu za moje potrebe, dokler nisem ugotovil, da se lahko zaviti zaklepaj "}" pojavi tudi nekje v sredini odseka in mi popolnoma zmede regex, ker ne ujame celotnega bloka, pac pa samo do prvega zavitega zaklepaja.

Primer dveh vnosov v datoteki:

lease 10.20.30.46 {
starts 3 2008/08/06 11:43:01;
ends 6 2008/08/09 11:43:01;
tstp 6 2008/08/09 11:43:01;
cltt 3 2008/08/06 11:43:01;
binding state free;
hardware ethernet cc:vv:cc:vv:cc:vv;
}
lease 10.20.30.45 {
starts 6 2008/08/16 22:49:35;
ends 1 2008/08/18 22:49:35;
tstp 1 2008/08/18 22:49:35;
cltt 6 2008/08/16 22:49:35;
uid "\001\000P\177\211}\024";
binding state active;
next binding state free;
hardware ethernet xx:yy:xx:yy:xx:yy;
}
V spodnjem primeru je v "uid" nizu tudi zaviti zaklepaj, moj izraz pa ujame vsebino samo do tja, namesto do konca niza, kar seveda ni OK, ker ne morem za ta IP dobiti podatkov, ki se nahajajo dalje od }.

Nisem prevec domac z regularnimi izrazi, zato bi prosil za pomoc pri tem. Potrebujem izraz, ki bi ujel celoten tekst od vkljucno besede "lease" pa do zadnjega zavitega zaklepaja, ki zakljucuje ustrezni blok za doticni lease.

Hvala.
"[...] the advance of civilization is nothing
but an exercise in the limiting of privacy."
- Isaac Asimov

b ::

Glede na to, da omenjaš preg_match, delaš verjetno v PHP-ju. Ker imaš v bistvu zlo lep input, bo najlažje, če uporabiš multiline match, ter iščeš zadnji zaviti oklepaj po tem, da je sam v eni vrstici, tisti vmes 100% niso sami.

Torej nekaj takega:

$subject="prebran dhcpd.leases";
$pattern="/^lease (\d+\.){3}\d+ \{$.*?^\}$/m";
preg_match($pattern,$subject);

To bi ti moralo ujet vse med vrstico lease in prvo naslednjo vrstico, v kateri je samo zaviti zaklepaj (vključno z obema vrsticama). Mimogrede, \r\n\s je nekoliko odveč, ker \s ujame ves whitespace, vključno z \r in \n :)

Escapati moraš tudi zavite oklepaje, ker se v regularnih izrazih sicer uporablja {n,m} za n-kratno ponovitev tega, kar je pred tem. Npr. \s{2,5} matchne 2-5 whitespaceov na kupu. Ali pa, kot vidiš v mojem primeru, (\d+\.){3}\d+ matchne IP naslov. 3x številka pika + številka.

Pa da razložim zgornji regularni izraz. Razdelimo ga na 3 dele:

^lease (\d+\.){3}\d+ \{$
.*?
^\}$

prvi matchne prvo vrstico. Drugi matchne vse kar pride za tem, a je zaradi vprašaja "non-greedy", se pravi ujame najmanj, kar je možno, da regularni izraz kaj matchne. Tretji del je oglati zaklepaj v svoji vrstici. Zaradi modifierja m (multiline match), imaš lahko v regularnem izrazu večkrat ^ in $, ki lahko matchneta vsak začetek in konec vrstice v stringu, po katerem iščemo.

Upam, da ti je to kaj v pomoč. Sicer pa priporočam knjigo "Mastering Regular Expressions". Jaz sem jo 10+ let nazaj našel v CTK, pa mi še zdaj ni nič žal, da sem jo prebral :)

McAjvar ::

Ahh, multiline in dottal mode je tisto, kar sem rabil, najlepsa hvala! Ja, trenutno je tole v PHPju, vendar se zna zgodit, da kmalu ne bo vec, zato nisem specificno omenil uporabljenega jezika.

Glede \r in \n se popolnoma strinjam, da sta odvec :)

Zaenkrat kaze, da tole deluje (za PHP):
$regexp = "/lease\s*([\d\.]+)\s*\{$.*?^\}\s*/ms";

Torej, modifyer m za multiline matching in s, da . ujame tudi newline znake, ki jih sicer ne. \s+ oz. \s* imam pa nametane zato, ker je ponekod dejansko malo vec whitespace znakov, odvisno, kako pridno je kdo rocno haral po datoteki. Oklepaji so na mestu, da izpljunejo IP naslov, IP matching je pa zelo poenostavljen, ampak dela :)

Se enkrat, hvala!
"[...] the advance of civilization is nothing
but an exercise in the limiting of privacy."
- Isaac Asimov


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Kako narediti python "cmd line" program

Oddelek: Programiranje
111591 (1014) ragezor
»

PHP sortiranje Arraya

Oddelek: Programiranje
81249 (1104) keworkian
»

kako pobrat iz html kode podatke

Oddelek: Izdelava spletišč
131740 (1410) qshop
»

[PHP]edit box problemček

Oddelek: Programiranje
6859 (773) sverde21
»

[PHP] Funkcija ki najde eno besedo v tekstu

Oddelek: Izdelava spletišč
11941 (849) McAjvar

Več podobnih tem