【问题标题】:Why is my perl replace not working?为什么我的 perl 替换不起作用?
【发布时间】:2014-05-24 15:55:25
【问题描述】:

我有以下 perl 搜索和替换:

带有转义:

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 

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

我不断收到错误:-sh: syntax error near unexpected token)'`,我不禁觉得这是因为我的一些愚蠢的逃避。请帮帮我。

【问题讨论】:

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

标签: html regex perl shell replace


【解决方案1】:

当您不使用单线时,有些事情会更容易。可以逃脱的东西更少,也没有那么脆弱。

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

【讨论】:

    【解决方案2】:

    [您没有指定要为哪个 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
    

    【讨论】:

      【解决方案3】:

      使用下一个:

      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\"//"
      

      应该可以。

      【讨论】:

        猜你喜欢
        • 2012-01-18
        • 1970-01-01
        • 2015-02-21
        • 1970-01-01
        • 1970-01-01
        • 2010-10-18
        • 2010-11-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多