1

我有 $html 其中包含 HTML 代码。在 HTML 中的某处有一个 id 为“content”的 DIV。我的目标是替换这个 DIV 的 HTML 内容。我在这个网站上读到,在处理 HTML 时最好使用解析器,而不是正则表达式。

到目前为止我做了什么(使用理想的 XPath):

my $tree= HTML::TreeBuilder::XPath->new();
$tree->parse_content($html);
$content = $tree->findnodes_as_string('//div[@id="content"]');

这给了我想要替换的 DIV 的整个 HTML 内容......但问题是如何替换这些内容?我试过(但没有用):

$html =~ s/$content/$newhtml/mgs;

谢谢您的帮助。

4

3 回答 3

3

Mojo::DOM支持 CSS 选择器而不是 XPath,我发现它在处理 HTML 时要简单得多。这将用in替换#content元素的内容:$newhtml$html

use Mojo::DOM;
my $dom = Mojo::DOM->new( $html );
$dom->at( '#content' )->replace_content( $newhtml );
print $dom;
于 2013-07-02T13:12:15.897 回答
2

你得到findnodes_as_string的只是一个字符串,它不再HTML::Element是保存文档的对象的一部分。如果您希望能够输出对象,则需要更新对象本身。

你需要使用findnodes来获取元素(你得到一个匹配元素的列表,取该列表中的第一个),然后你可以使用replace_with. 如果包含标记(即,如果它不是简单的文本内容) ,您可能需要将HTML::Element对象传递给。replace_with$newhtml

#!/usr/bin/perl

use strict;
use warnings;

use HTML::TreeBuilder::XPath;

my $html=q{<html><head><title>foo</title></head>
                 <body><div id="title">foo</div>
                       <div id="content"><p>1 para</p><p>2 para's</p></div>
                 </body>
          </html>};

my $new_content='<div id="content"><p>new para 1</p><p>new para 2</p></div>';

my $tree= HTML::TreeBuilder::XPath->new();
$tree->parse_content($html);

# findnodes erturns a list of elements, take the first one
my $div = ($tree->findnodes('//div[@id="content"]'))[0];
# replace the div with an element created from $new_content
$div->replace_with( HTML::TreeBuilder->new_from_content( $new_content));

print $tree->as_HTML;
于 2013-07-02T12:58:49.557 回答
0

可能$content包含在正则表达式模式中具有特殊意义的字符,即来自集合*+?|[]{}^$

你最好在保存模式的变量中转义元字符:

$html =~ s/\Q$content\E/$newhtml/mgs;

(详见此处)。

于 2013-07-02T12:35:44.317 回答