2010-08-27 32 views
2

我試圖在許多網站上重做很多頁面。除HTML之外,頁面可能包含JavaScript,PHP或ASP代碼。我遇到的問題是模塊重寫了我不想重寫的內容。我已設法處理HTML標記(例如script)中的大部分符號(例如,",>),但它們在php部分中變爲實體(例如,",>)。另外,php標籤同時被剝離出來。使用Perl修改PHP文件(可能使用HTML :: TreeBuilder)

如果我有一個PHP文件看起來像這樣:

<html> 
    <head><title>My Page</title></head> 
    <body> 
    <p>Some cruft &nbsp; 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 &nbsp; 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 &nbsp; 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) &gt; 2) 
     { 
      echo &quot; or &quot;; 
      if(isset($_REQUEST[&#39;nr&#39;])) 
     { 
      $numRows = $_REQUEST[&#39;nr&#39;]; 
      .... 
    ?> 
    </body> 
</html> 

我一直在使用HTML :: TreeBuilder 3.23。我試過開發​​者版本3.23_3,但由於php代碼的原因,它提供了一個錯誤消息(例如,a has an invalid attribute name '"&section_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; 

我願意接受任何建議,示例等我不必拘泥於到任何特定的模塊,但我不完全是一個專家程序員。

謝謝!

回答

3

這裏的問題顯然是<?php .. ?>標籤。你可以通過預備者來完成。我將使用一個簡單的正則表達式是:

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撤銷mangling(如字符編碼) - 這聽起來像是一個遠的更糟糕的想法給我。您甚至可以使用Template過濾器實現從__PHP_CODE__令牌到真正的PHP代碼的內容。

應該指出的是,這並不考慮短標籤(雖然它可以很容易!)並且,我不確定觸發PHP解釋器的邏輯(例如跳過<?php?>)。很明顯,儘管我會透露,這對PHP代碼沒有這樣的支持:

echo '?>'; 
+0

這看起來完全可行......假設我可以把我的頭包裝起來,讓它與代碼的其餘部分一起工作。感謝您的快速回復,並且在我咀嚼了一陣之後我會更新它。 – tmsilver 2010-08-27 18:02:04

+0

這似乎是工作,但我不得不做很多讀/寫才能使其工作。我最終1)讀取文件,用令牌替換PHP; 2)用令牌寫文件; 3)爲TreeBuilder讀取文件; 4)寫入TB更改的文件; 5)讀取文件,用代碼替換標記; 6)完整更改寫入文件。 如果我嘗試跳過其中的任何一個,它會省略或覆蓋我的一些更改。這可能是一個新手事物... 感謝您的幫助! – tmsilver 2010-08-27 21:46:56

+1

您不必多次「寫入文件」。你可以在記憶中完成這一切。您可以(1)* slurp *文件,(2)分配php令牌(3)使用TreeBuilder運行'new_from_content',(4)轉換,(5)' - > as_HTML'它,(6)運行正則表達式替換PHP令牌(7)一次寫入文件。這仍然是記憶中的許多傳球 - 許多理論上不需要,但這仍然不是文件io。 – 2010-08-27 22:07:25