在Perl搜索中正确地转义doctype声明字符串



使用Perl find,我无法成功地转义搜索字符串中的DOCTYPE声明。下面是一个我正在搜索的字符串示例;

find . -type f|xargs -d "n" perl -pi -e 's/ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">//g'  

以不使用任何内容替换doctype声明。如果有人能正确地转义这个字符串,以便perl查找可以找到任何字符串,我们将不胜感激。

正如另一个人所建议的,正则表达式中的各种'/'字符需要用''转义,因为Perl会将它们读取为过早结束s///;,否则会导致一些错误。在处理这些问题时,你总是要注意特殊的角色,就像我看到你在不同时期所做的那样。

's/ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">//g' 

您可以将s///;中的分隔符更改为其他内容,例如s###s{}{}来帮助解决问题,如果您使用HTML,我通常建议您这样做。

即便如此,我还是要尽量简化正则表达式,使其适用于应用程序。因为像这样的HTML可能很难处理,所以尝试使用非贪婪匹配任何类型的正则表达式,但使用<>来捕获特定的标记。例如,您可以使用这样的regex。。。

s{<!DOCTYPE .*?>}{}s

还有一些解释性的格式。。。

s{
<!DOCTYPE   # opening doctype tag
s          # one whitepsace
.*?         # anything (even newlines because of /s flag) non-greedily
>          # until the first closing greater than 
}{}xs;          # x is ignore whitespace, s is have '.' match anything (even n)

本例使用/x标志对其进行注释并解释所有内容,但如果您在命令行中执行此操作,则没有必要这样做。

我无法回答您问题的其余部分,因为我对shell命令不太熟悉,只熟悉regex部分。

您可以在Perl中使用除/之外的其他分隔符。试试这个:

s{<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">}{}g

由于斜杠不再对正则表达式进行分隔,因此使用它是安全的。

如果DOCTYPE在一行,最好这样写:

find . -type f -exec sed -i '/DOCTYPE/d' {} +

或在perl:中

find . -type f -exec perl -i -ne 'print unless /DOCTYPE/' {} +

以避免空行。

注意

  • -i开关修改文件。出于测试目的将其删除

虽然已经涵盖了备用分隔符(例如s###),但我会使用QE添加以消除其他转义需求:

s#Q<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">E##g' 

最新更新