2013-05-03 75 views
0

我有一個HTML文件的文件夾,它具有我需要刪除的下面的DOCTYPE聲明,這樣一個不太好的解析器可以成功地將它加載爲XML。如何觸發Perl多行替換

我一直在嘗試使用perl來完成替換,但是當我運行替換時沒有發生變化,我找不到原因。任何人都可以識別出正確的標誌或規範,我需要在這裏刪除DOCTYPE處理指令。

這是我想操作的示例文件。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <meta name="generator" content= 
    "HTML Tidy for Linux/x86 (vers 25 March 2009), see www.w3.org" /> 
    <title></title> 
</head> 
    <body> 
    </body> 
</html> 

這裏的Perl的一個班輪我試圖使用,這看起來對尖括號,感嘆號,一切都結束尖括號之前。它包含perl替換標誌,其他帖子建議應該用於多行匹配 - m用於多行,s用於允許換行符與正則表達式匹配。然後我用空字符串替換匹配。

perl -i -e 's/<![^>]+>//gsm' `find . -name '*.html'` 

我不明白爲什麼,但運行此命令後DOCTYPE不會從文件中刪除。其他人知道爲什麼嗎?

回答

1

你需要的是-0777開關,它會導致整個文件被讀入一個字符串。如果不使用這些文件,那麼這些文件將以逐行模式讀取,並且您無法以這種方式匹配多行語句。

另外,正如Andomar指出的那樣,您錯過了-p開關,但我想你已經明白了。

除了/g修飾符以外,在這種情況下,正則表達式上的修飾符無關緊要。 /m僅影響^$,/s導致通配符.也匹配換行符。這不適用於你的正則表達式。

所以基本上,你想要的東西,如:

perl -0777 -pi -e 's/<![^>]+>//g' ... 

旁註:

的Html應該分析器,理想地處理,所以我花了幾分鐘的工作使用HTML::Parser通過添加處理程序可以方便地選擇去除聲明。像這樣的東西似乎打印OK的單個文件:

perl -MHTML::Parser -we ' 
    $p = HTML::Parser->new(default_h => [sub {print @_},'text']); 
    $p->handler(declaration => ''); 
    $p->parse_file(shift) or die $!; " yourfile.html 

我想這將是矯枉過正,所以我放棄了嘗試與-pi就地編輯交換機修復它,但它是(可能)中很容易實現一個腳本。

+0

我可以從這個答案和附註中瞭解到整個負載,謝謝你付出的努力! – user2257198 2013-05-28 16:26:40

+0

不客氣。 – TLP 2013-05-28 16:50:52

1

首先,您似乎缺少參數-p,用於逐行處理輸入。 -i似乎沒有太多的-p

其次,由於-pi逐行處理輸入,因此無法替換跨越多行的正則表達式。

您可以改爲編寫Perl腳本。該腳本應在命令行上傳遞的所有文件的全部內容運行的正則表達式:

use IO::All; 

foreach my $file (@ARGV) { 
    my $content = io($file)->slurp; 
    $content =~ s/<![^>]+>//g; 
    $content > io($file); 
} 

命令cpan IO:All應該安裝IO:All模塊,如果它不存在您的系統上。

P.S. ms選項僅影響.,^$。我想你可以省略它們。

+0

也沒有工作,(安裝CPAN IO後:所有),雖然我不知道多是默認的(沒有「M」標誌的代換系)。恥辱這是不可能的一個單線,但感謝負載。 – user2257198 2013-05-03 12:43:55

+0

@ user2257198你*已*注意到我的答案,對吧?我只是想知道爲什麼當我的回答給你這樣一個單行的時候,你說「羞辱它不可能與一行」。 – TLP 2013-05-03 12:55:38