Добавьте начальный и конечный обработчики в свой анализатор и попросите их записать происхождение текущего элемента.Если в наследстве содержится <head>
или <script>
, отключите переписывание.
Сохраните текст *
#! /usr/bin/perl
use warnings;
use strict;
use HTML::Parser 3.05;
sub edit_print { local $_ = shift; tr/a-z/n-za-m/; print }
и используйте следующую подпрограмму для создания нового анализатора:
sub create_parser {
my @tags;
my $start = sub {
my($text,$tagname) = @_;
push @tags => $tagname;
print $text;
};
my $end = sub {
my($text,$tagname) = @_;
die "$0: expected </$tags[-1]>, got </$tagname>"
unless $tagname eq $tags[-1];
pop @tags;
print $text;
};
my $edit_print = sub {
if (grep /^(head|script)$/, @tags) { print @_ }
else { edit_print @_ }
};
HTML::Parser->new(
unbroken_text => 1,
default_h => [ sub { print @_ }, "text" ],
text_h => [ $edit_print, "text" ],
start_h => [ $start, "text,tagname" ],
end_h => [ $end, "text,tagname" ],
);
}
Причиной создания его внутри подпрограммы является обратный вызов обработчика замыканий, которые разделяют частное состояние в @tags
.Эта реализация позволяет создавать экземпляры нескольких синтаксических анализаторов, не беспокоясь о том, что они могут помешать друг другу.
my $p = create_parser;
$p->parse_file(\*DATA);
__DATA__
foo
<html>
<head>
<title>My Title</title>
<style type="text/css">
/* don't change me */
</style>
</head>
<body>
<script type="text/javascript">
// or me
</script>
<h1>My Document</h1>
<p>Yo.</p>
</body>
</html>
Вывод:
sbb
<html>
<head>
<title>My Title</title>
<style type="text/css">
/* don't change me */
</style>
</head>
<body>
<script type="text/javascript">
// or me
</script>
<h1>Ml Dbphzrag</h1>
<p>Yb.</p>
</body>
</html>