Newsgroup: it.comp.lang.perl
Titolo: Aiuto: Regular expressions

Sto cercando disperatamente di creare una regexp che riesca a leggere dei
tags annidati da dentro verso fuori.
Mi spiego meglio.
Sto creando un parser che legge da un file html e interpreta alcuni meta
tags proprietari.
<if:expr><if:expr> bla bla bla </if> strabla strabla </if>
come faccio per estrarre prima i tag piu' interni?
Se uso 
s/(<if:.*?>.*?<\/if>)/handler($1)/ge;
ovviamente ottengo dal primo tag di apertura al primo di chiusura.
Ma a me interessa estrarre dal tag di apertura piu' interno a quello di
chiusura corrispondente.
Come diavolo fare?
Grazie, salvate una vita.
Aekidna.

Come diavolo fare?
devi fare in modo che fra <inizio> e <fine> non sia compreso
<inizio> :)
Oha

complimenti per la genialita'!! :)
Dai, qualcuno vuole salvarmi la pelle?
Ci sono un giorno intero sopra sto problema.
Utilizzando [^<inizio>] mi valuta ogni carattere di "<inizio>" anziche' la
stringa interaaaaaaaaaa!!!! maledetta regexp.
Help!! I need somebody Help!!!!!!
In 
frnhss4rn3fuvm3nu...@4ax.com
, oha, 
o...@oha.it
, il


 Grazie, salvate una vita.
Mi chiedo perche' tutte le domande poste qui debbo essere
questioni di vita o di morte, cose urgentissime senza le quali il mondo
finira' domani pomeriggio.
Esiste una regola semplice: se la vostra e' una questione di vita o di
morte, non usate Usenet. Niente garantisce che il messaggio parte o che la
gente lo legga subito.
Passando alle cose serie, una semplice regexp puo' non essere sufficiente.
Come dice la risposta alla domanda "Can I use Perl regular expressions to
match balanced text?" in perlfaq6 (straordinario come ci siano cose cosi'
inutili nelle FAQ per cui non valga proprio la pena di provare a leggerle "a
prescindere"), non e' in genere possibile fare il matching con una regexp
singola.
Siccome mi piace esagerare, penso che nel tuo caso un bel modulo come
Text::Balanced (altro nome insospettabile) possa funzionare, anche se il suo
uso non e' dei piu' chiari.
Ho provato il seguente programma:
#!/usr/bin/perl
use Text::Balanced qw/extract_tagged/;
$val = "<if:expr><if:expr> bla bla bla </if> strabla strabla </if>";
($tutto,$resto,undef,undef,$testo) =  
              extract_tagged($val,'<if:.*?>','</if>');
print "1:\nTra tag: $tutto\nResto: $resto\nTesto bilanciato: $testo\n";
($tutto,$resto,undef,undef,$testo2) =
              extract_tagged($testo,'<if:.*?>','</if>');
print "2:\nTra tag: $tutto\nResto: $resto\nTesto bilanciato: $testo2\n";
__END__
Che mi produce il seguente output:
1:
Tra tag: <if:expr><if:expr> bla bla bla </if> strabla strabla </if>
Resto:
Testo bilanciato: <if:expr> bla bla bla </if> strabla strabla
2:
Tra tag: <if:expr> bla bla bla </if>
Resto:  strabla strabla
Testo bilanciato:  bla bla bla
e forse fa quasi quello che vuoi. Se il tag non e' all'inizio della stringa,
le cose diventano un po' piu' tricky, ad esempio con
$val = "aaa <if:expr><if:expr> bla bla bla </if> strabla strabla </if> bbb";
devi usare
($tutto,$resto,undef,undef,$testo) =
              extract_tagged($val,'<if:.*?>','</if>','.*?(?=<if:.*?>)');
print "1:\nTra tag: $tutto\nResto: $resto\nTesto bilanciato: $testo\n"; 
per ottenere
1:
Tra tag: <if:expr><if:expr> bla bla bla </if> strabla strabla </if>
Resto:  bbb
Testo bilanciato: <if:expr> bla bla bla </if> strabla strabla 
'aaa ' sarebbe finita nel primo undef.
Buon divertimento.
Ah. A pensarci bene forse HTML::Parser o HTML::TokeParse o qualche altro
modulo di quella famiglia potrebbero anche fare a caso tuo, ma per stasera
ho finito.
Maurizio
-- 
Maurizio M. Munafo' / 
mmmu...@netscape.net
"Consider Phlebas, who was once handsome and tall as you" (T.S.Eliot)

 Help!! I need somebody Help!!!!!!
Citazione inutile. Temo che potrei rispondere con un detto popolare, ma
preferisco evitare :)


 ha scritto nel messaggio
news:8qarhj$9s6$1...@menelao.polito.it...



Non importa. Ho gia' risolto per conto mio. Grazie lo stesso.
Il mio messaggio precedente non era per insistere, era un semplice reply
alla scherzosa risposta di oha solo che erroneamente non riusultava nello
stesso thread. Scusate.
E comunque lo so bene che [^...] valuta una classe di caratteri. Bisonerebbe
utilizzare un corrispondente negativo di (?:expression) solo che non sono
riuscito a trovare la formula giusta.
In pratica la regexp deve dire:
trova <inizio> bla bla che non contenga "<inizio>" </fine>;
L'ho risolta cosi':
s/(<ar>.*?<\/ar>)/substr($1,0,(rindex($1,'<ar>')))
.handler(substr($1,(rindex($1,'<ar>'))))/ges;
infilando questa regext in una while vengono analizzati i tags
corrispondenti dai piu' interni verso l'esterno.
Ciao a tutti e grazie.
Aekidna.
In 8qaseb$9s6$
3...@menelao.polito.it
, Maurizio M. Munafo`,
