Как я могу переписать текстовые части HTML, используя HTML :: Parser, не изменяя разделы <script>и <head>? - PullRequest
2 голосов
/ 23 июля 2010

Следующий код является сокращенной версией пример из HTML :: Parser

#!/usr/bin/perl -w
use strict;
my $code = shift || usage();
sub edit_print { local $_ = shift; tr/a-z/n-za-m/; print } 
use HTML::Parser 3.05;
my $p = HTML::Parser->new(unbroken_text => 1,
     default_h => [ sub { print @_; }, "text" ],
     text_h    => [ \&edit_print,      "text" ],
);
my $file = shift;
$p->parse_file($file)

Этот код работает довольно хорошо, но имеет недостатокчто он также переписывает текст внутри <script>, а также <head> разделов.Я адаптировал приведенный выше пример, чтобы сделать то, что я хочу, но, к сожалению, есть еще одна ошибка, которая переписывает такие вещи, как текст внутри тега <title>, который я не хочу переписывать.знаете, как написать что-то подобное выше, но без искажения JavaScript, <title> или других разделов?Я счастлив использовать другой модуль помимо HTML :: Parser, если это необходимо.

Ответы [ 2 ]

2 голосов
/ 23 августа 2010

Добавьте начальный и конечный обработчики в свой анализатор и попросите их записать происхождение текущего элемента.Если в наследстве содержится <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>
0 голосов
/ 23 июля 2010

Глядя на ваш существующий код, я не уверен, где вы застряли:

  1. добавить стек логических значений

    my @do_edit = (0)
    
  2. в edit_print, не редактируйте, если $ do_edit [0] равно 0

  3. добавить обработчики start_h и end_h для сдвига / снятия значений для определенных имен элементов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...