为什么我的perl替换不起作用?

时间:2014-04-10 18:51:10

标签: html regex perl shell replace

我有以下perl搜索和替换:

使用Escapes:

perl -pi -w -e 's/ onclick=\"img=document.getElementById(\'img_1\')\; img.style.display = (img.style.display == \'none\' ? \'block\' : \'none\');return false"//' test.html 

没有逃脱:

perl -pi -w -e 's/ onclick="img=document.getElementById('img_1'); img.style.display = (img.style.display == 'none' ? 'block' : 'none');return false"//' test.html 

我的目标是在onclick="img=document.getElementById('img_1'); img.style.display = (img.style.display == 'none' ? 'block' : 'none');return false"文件中没有任何内容替换test.html。我搞砸了什么?

我继续得到错误:-sh: syntax error near unexpected token)'`我不禁感到因为我的一些愚蠢的逃避。请帮帮我。

3 个答案:

答案 0 :(得分:3)

[您没有指定构建命令的shell。我将假设shbash。 ]


问题#1:将文本转换为正则表达式

许多字符在正则表达式中具有特殊含义。在您使用的用户中,().?都很特殊。这些都需要逃脱。

如果你想匹配

onclick="img=document.getElementById('img_1'); img.style.display = (img.style.display == 'none' ? 'block' : 'none');return false"

您需要使用模式

onclick="img=document\.getElementById\('img_1'\); img\.style\.display = \(img\.style\.display == 'none' \? 'block' : 'none'\);return false"

所以你的Perl代码是

s/onclick="img=document\.getElementById\('img_1'\); img\.style\.display = \(img\.style\.display == 'none' \? 'block' : 'none'\);return false"//

问题#2:将文本(Perl程序)转换为shell文字

这是你问过的问题。

单引号引用的部分(“'”)在下一个单引号(无条件)结束,因此以下是错误的:

echo 'foo\'bar'   # Third "'" isn't matched.

如果您想输出“foo'bar”,可以使用

echo 'foo'\''bar'   # Concatenation of "foo", "'" and "bar".

foobar由单引号引用,单引号使用\进行转义。 \在这里工作,因为它不在单引号内。

因此,该课程基本上是在单引号内使用'\''而不是'

您想将以下程序传递给Perl:

s/onclick="img=document\.getElementById\('img_1'\); img\.style\.display = \(img\.style\.display == 'none' \? 'block' : 'none'\);return false"//

为此,您需要创建一个生成正确参数的shell文字,这意味着我们希望用单引号括起整个文本并转义现有的单引号。我们得到以下信息:

's/onclick="img=document\.getElementById\('\''img_1'\''\); img\.style\.display = \(img\.style\.display == '\''none'\'' \? '\''block'\'' : '\''none'\''\);return false"//'

因此,整个命令将是

perl -i -wpe's/onclick="img=document\.getElementById\('\''img_1'\''\); img\.style\.display = \(img\.style\.display == '\''none'\'' \? '\''block'\'' : '\''none'\''\);return false"//' test.html

答案 1 :(得分:1)

使用下一个:

perl -lnE 'say quotemeta $_'

并用您的普通输入提供:

onclick="img=document.getElementById('img_1'); img.style.display = (img.style.display == 'none' ? 'block' : 'none');return false" 

你会得到:

onclick\=\"img\=document\.getElementById\(\'img_1\'\)\;\ img\.style\.display\ \=\ \(img\.style\.display\ \=\=\ \'none\'\ \?\ \'block\'\ \:\ \'none\'\)\;return\ false\"

所以使用它:

perl -i -pe "s/onclick\=\"img\=document\.getElementById\(\'img_1\'\)\;\ img\.style\.display\ \=\ \(img\.style\.display\ \=\=\ \'none\'\ \?\ \'block\'\ \:\ \'none\'\)\;return\ false\"//"

应该有用。

答案 2 :(得分:0)

当您不使用单行时,有些事情会更容易。逃避的事情少,而不是脆弱。

use strict;
use warnings;

my $literal_string = q{ onclick="img=document.getElementById('img_1'); img.style.display = (img.style.display == 'none' ? 'block' : 'none');return false"};

while (<>) {
    s/\Q$literal_string//;
    print;
}

然后执行脚本:

perl -i thescript.pl test.html