Newsgroup: it.comp.lang.perl
Titolo: espressione regolare con esclusione dei commenti HTML

Salve,
avrei bisogno di una dritta con le espressioni regolari per fare un parsing 
su codice HTML.
Devo verificare nel codice sorgente HTML la presenza della stringa "HELLO", 
ed ovviamente per fare questo con le espressioni regolari basterebbe:
/(HELLO)/
Il problema è che devo anche escludere il riconoscimento della stringa 
"HELLO" quando si trova inserita all'interno di un commento HTML, e cioè 
quando si trova racchiusa tra il tag di inizio commento "<!--" e quello di 
fine commento "-->".
In pratica devo riconoscere la stringa HELLO nel caso a) mentre devo 
ignorarla nel caso b)
a) ... HELLO ...
b) <!-- ... HELLO ... -->
Devo usare qualcosa dal genere ?
(?<!foo)
Qualche suggerimento ?
Grazie anticipatamente,
Riccardo
-- 

Riccardo wrote:

Si potrebbe anche fare (esclusivamente) con delle regex, ma sarebbe 
troppo fragile, perché dovresti contemplare troppi casi in cui 
ugualmente non vorresti catturare il testo: ad esempio pensa al caso in 
cui la stringa "HELLO" si trovasse nell'attributo di un tag (guarda il 
codice fornito).
Molto meglio usare uno dei parser HTML disponibili su CPAN: ottieni 
codice molto più robusto ed anche più semplice e leggibile.
Segue un esempio (funzionante).
Ciao, Emanuele
-----
use strict;
use warnings;
use HTML::TokeParser::Simple;
my $page = HTML::TokeParser::Simple->new( \*DATA );
while ( my $token = $page->get_token ) {
     next if $token->is_comment;
     next unless $token->is_text;
     my $text = $token->as_is;
     print $text, "\n-----\n" if $text =~ /HELLO/
}
__DATA__
<html>
<div class="HELLO">Da scartare perche` e` in un attributo</div>
<!-- Da scartare perche` HELLO è in un commento -->
<div>
     Qui HELLO e` da prendere!
     <!-- ma qui HELLO e` da riscartare -->
     Qui HELLO e` da RIprendere!
</div>
</html>

     next unless $token->is_text;
Anzi si può fare ancora più breve, perché basta invocare il solo metodo 
is_text(), che già scarta automaticamente i commenti:
use strict;
use warnings;
use HTML::TokeParser::Simple;
my $page = HTML::TokeParser::Simple->new( \*DATA );
while ( my $token = $page->get_token ) {
     next unless $token->is_text;
     my $text = $token->as_is;
     print $text, "\n-----\n" if $text =~ /HELLO/
}
__DATA__
<html>
<div class="HELLO">Da scartare perche` e` in un attributo</div>
<!-- Da scartare perche` HELLO e` in un commento -->


 ...
Grazie, sei stato comunque molto gentile...
Riccardo

 ...
Grazie per entrambe le risposte,
ma il mio esempio è stato volutamente semplificato... non credo che 
is_text() andrebbe bene.
In realtà non devo catturare una semplice stringa "HELLO" ma qualcosa di 
leggermente più complicato...  cioè un certo link.
Devo individuare la presenza di un link del tipo 
http://www.mylink.it
 
all'interno di un tag anchor (<a ... href="
http://www.mylink.it
" ... 
 >...</a>).
Il problema è che devo ovviamente escludere i casi in cui tale tag fosse 
presente all'interno di un commento:
<!-- ... <a ... href="
http://www.mylink.it
" ... >...</a> ... -->
Riccardo
-- 

 <!-- ... <a ... href="
http://www.mylink.it
" ... >...</a> ... -->
Allora a maggior ragione è d'obbligo un parser html: solo con le regex 
sarebbe fragilissimo (e in php è ancora peggio ;-)
Per chi fosse interessato: su CPAN ci sono dei wrapper di HTML::Parser 
specializzati per i link, che permetterebbero di farlo in due righe di 
codice, e in maniera corretta (presumo che anche php ne abbia).
Capisco le tue esigenze contingenti, ma non so se qui possa esserti 
d'aiuto qualcuno, anche perché le regex del Perl non sono la stessa cosa 
delle PCRE di php.
Inoltre, in particolare quando si chiede una regex, le specifiche devono 
essere più che rigorose e coprire *tutti* i casi possibili, altrimenti 
si rischia di perdere soltanto del tempo (io in ogni caso passo).
Ciao

 modificando la mia attuale espressione regolare per il match.
Allora devi chiedere in un gruppo PHP...
Non conosco il PHP, ma forze ce` una libreria che ti lascia usare XPATH 
sull'HTML, che penso serrebe l'unico modo di averre un resultato robusto.
-- 
mirod (che non scrive bene l'italiano)