PDA

Pogčedajte punu verziju : RegEx za nested curly brackets


vsavic
20. 08. 2011., 13:02
Pozdrav, imam ovakav input string:

Main {
name 1 = value 1
name 2 = value 2
}
Main {
name 1 = value 1
name 2 = value 2
sub {
name 1 = value 1
...
}
}

i ovakav regex (trenutno)

Main\s*?{(?<OptionsParams>[^}]+)}


Kako da moj regex uhvati sve sto je i u donjem delu "Main" tj. da poklopi pravilno "}" zagradu koju treba a ne prvu na koju naleti.

Napomena, ne koristi se .NET tako da ne mogu da koristim balanced groups.

Hvala unapred

miks
20. 08. 2011., 16:40
Mozda nesto ovako (perl sintaksa):

Main[^{}]*\{([^{}]*|(?:[^{}]*\{[^{}]*\}[^{}]*)*)\}

vsavic
20. 08. 2011., 16:55
Hvala puno! :)

ivanhoe
21. 08. 2011., 11:35
u ko jeziku radis? U principu se takve stvari uvek resavaju rekurzijom, a u PHP-u ima preg_replace_callback() koji je zgodan za rad sa ugnjezdenim strukturama... pogledaj php help, ima primer za nested BB code...

ako ne zelis da radis replace, nego samo match, naprosto vratis isto sto je matchovano

vsavic
22. 08. 2011., 10:04
u ko jeziku radis? U principu se takve stvari uvek resavaju rekurzijom, a u PHP-u ima preg_replace_callback() koji je zgodan za rad sa ugnjezdenim strukturama... pogledaj php help, ima primer za nested BB code...

ako ne zelis da radis replace, nego samo match, naprosto vratis isto sto je matchovano

Ok, rekurzijom sam i mislio, ali problem je bilo match-ovanje, i ovo gore ipak ne radi za strukturu gde imam pod sekciju u pod sekciji (znaci kad po dubini imam jos ugnjezdenih sekcija).

Ajd ako te ne mrzi postuj to resenje koje ti imas koje kazes da bi radilo.

jablan
22. 08. 2011., 10:23
Jel samo treba da izvučeš ove glavne delove (koji počinju sa Main) ili te interesuje i sadržaj? Nisi baš precizno postavio pitanje.

vsavic
22. 08. 2011., 10:36
Jel samo treba da izvučeš ove glavne delove (koji počinju sa Main) ili te interesuje i sadržaj? Nisi baš precizno postavio pitanje.

Trebao bi mi i sadrzaj.
Tj. sve ono unutar te glavne sekcije koju trazim.

Ako imam vise istoimenih sekcija trebao bi mi sadrzaj svake od njih kao array neki, a u tom sadrzaju da se nadju i podsekcije.

Dakle za onaj moj slucaj da dobijem ovako nesto:

Prvi match:
name 1 = value 1
name 2 = value 2

Drugi match:
name 1 = value 1
name 2 = value 2
sub {
name 1 = value 1
...
}

Da posle mogu opet u okviru ovog drugog match-a da pustim isti regex da dobijem ono sto se nalazi u podsekciji i tako u dubini dokle treba.

Nadam se da sam sad malo pojasnio.

Inace zaboravih gore da kazem, da, PHP bi odgovarao.

miks
22. 08. 2011., 17:58
$str = ' Main ... ';
$rex = '!Main[^{}]*\{([^{}]*|(?:[^{}]*\{[^{}]*\}[^{}]*)*)\}!si';
while (preg_match($rex, $str, $m)) {
// do whatever ...
$str = str_replace($m[0], "", $str);
}

ivanhoe
22. 08. 2011., 21:56
Mozes jednostavno ovako


function parse_section($section, $input) {
//ocistimo visak znakova
$re = '/^\s*' . $section .'\s*{\s*|}$/s';
$input = preg_replace($re, '', $input);
// podelimo na sekcije
$re = '/\s*}\s*' . $section .'\s*{/s';
return preg_split($re, $input);
}
// $input je tvoj string
$sekcije = parse_section('Main', $input);
print_r($main);

// pa onda dalje mozes da pozoves parse_section('sub,...) da pokupis ono unutra

vsavic
23. 08. 2011., 15:58
Ivane, to je to, hvala.
Imas pivo :)