sub parseur { my $stuff = shift; # Build a hash out of a list of "atomic" tags, # i.e. tags which are not normally closed. my %atomic = map {($_=>1)} qw [ hr br p img li option ]; my @stack; my $start_h = sub { my ($tagname,$attr) = @_; push (@stack, $tagname) unless $atomic{$tagname}; }; my $end_h = sub { my ($tagname) = @_; # Find the last entry in the stack which corresponds... foreach my $i ($#stack .. 0) { if ($stack[$i] eq $tagname) { # ...and remove it. splice (@stack, $i, 1); } } }; my $parser = new HTML::Parser ( start_h => [ $start_h, 'tagname,attr' ], end_h => [ $end_h, 'tagname' ], ); $parser->parse ($stuff); }