我正在尝试在许多网站上修改许多网页。除HTML之外,页面可能还包含JavaScript,PHP或ASP代码。我遇到的问题是模块重写了我不想重写的东西。我设法处理了像"
这样的HTML标记中的大多数符号(例如>
,script
),但它们变成了实体(例如"
, {php}部分中的>
)。另外,php标签同时被删除。
如果我有一个看起来像这样的PHP文件:
<html>
<head><title>My Page</title></head>
<body>
<p>Some cruft which I want to repeat</p>
<form name="foo"> (form content to be replaced)
</form>
<script type="JavaScript">
<!--
Some javaScript to be left alone
-->
</script>
<a href="somepage.php">Link to be removed</a>
<?php
if (strlen($txtKeyword) > 2)
{
echo " or <a href=\"database_search_keyword.htm\">Search again?</a></p>";
if(isset($_REQUEST['nr']))
{
$numRows = $_REQUEST['nr'];
....
?>
</body>
</html>
我希望最终结果如下:
<html>
<head><title>My Page</title></head>
<body>
<p>Some cruft which I want to repeat</p>
<ul><li>List replacing form</li>
</ul>
<script type="JavaScript">
<!--
Some javaScript to be left alone
-->
</script>
<?php
if (strlen($txtKeyword) > 2)
{
echo " or <a href=\"database_search_keyword.htm\">Search again?</a></p>";
if(isset($_REQUEST['nr']))
{
$numRows = $_REQUEST['nr'];
....
?>
</body>
</html>
正如我所说的,除了php之外,我能够完成所有工作。它被管理,结果
<html>
<head><title>My Page</title></head>
<body>
<p>Some cruft which I want to repeat</p>
<ul><li>List replacing form</li>
</ul>
<script type="JavaScript">
<!--
Some javaScript to be left alone
-->
</script>
<?php
if (strlen($txtKeyword) > 2)
{
echo " or ";
if(isset($_REQUEST['nr']))
{
$numRows = $_REQUEST['nr'];
....
?>
</body>
</html>
我一直在使用HTML :: TreeBuilder 3.23。我已经尝试过开发人员版本3.23_3,但由于php代码(例如,a has an invalid attribute name '"§ion_id' ' . $section_id . '
),它会给出错误消息。
到目前为止我所做的示例代码(文件系统走路等被砍掉)是
#!/usr/bin/perl -w
use strict;
use HTML::TreeBuilder;
# Set up replacement forms
my $artistSearch = HTML::Element->new ('~literal', 'text', <<EOF);
<p>Please select from the list below.</p>
<ul>
<li><a href="http://firstlink.com/">item 1</a></li>
<li><a href="http://secondlink.com/">item 1</a></li>
</ul>
EOF
my $filename = "AFA.php";
my $file = HTML::TreeBuilder->new();
$file->store_comments(1);
$file->ignore_ignorable_whitespace(1);
$file->no_space_compacting(1);
my $tree = $file->parse_file($filename);
my $form = $tree->find_by_tag_name('form');
my $fname = $form->attr('name');
if ($fname eq 'mainform') {
$form->delete;
} elsif ($fname eq 'artist_search') {
$form->replace_with($artistSearch)->delete;
} else {
# It's a form we're not changing
}
my $printout = $file->as_HTML("", " ", {});
open (PAGE, "> $filename");
print PAGE $printout;
close (PAGE);
$file->delete;
我对任何建议,示例等持开放态度。我不一定与任何特定模块绑定,但我不是一个专业的程序员。
谢谢!
答案 0 :(得分:3)
这里的问题显然是<?php .. ?>
标签。你可以用preparser完成这个任务。我将使用一个简单的正则表达式:
use strict;
use warnings;
undef $/;
$_=<>;
my @phps;
push @phps, $1 while s/<\?php (.*?) \?>/__PHP_CODE__/;
use Data::Dumper;
die Dumper [$_, \@phps];
你可以尝试一下:
echo "foo<?php phpfoo ?> bar <?php phpbar ?> baz" | filter.pl
$VAR1 = [
'foo__PHP_CODE__ bar __PHP_CODE__ baz',
[
'phpfoo',
'phpbar'
]
];
现在,当你完成它。您可以反过来将PHP代码从@phps
数组中取出并返回到输出中的正确顺序:
my $count = 0;
s/__PHP_CODE__/<?php $phps[$count++] ?>/g;
毫无疑问,这是一个黑客攻击;但是,它会毫不费力地完成你的工作。实现起来也相当简单。我可以考虑一些更好的方法来做到这一点 - 例如扩展HTML::Element
以包含伪<?php .. ?>
元素。你不想要的是在TT中通过HTML::Element
撤消修改(如字符编码) - 对我来说这听起来像是一个远更糟糕的想法。您甚至可以使用__PHP_CODE__
过滤器实现从Template
令牌到真实PHP代码的内容。
应该注意的是,这并没有处理短标签(虽然它很容易!)而且,我不确定触发PHP解释器的逻辑(转义<?php
或?>
例如)。很明显,虽然我会透露,这与PHP代码无关:
echo '?>';