2013-05-03 58 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