简体   繁体   English

为什么我的perl replace无法正常工作?

[英]Why is my perl replace not working?

I have the following perl search and replace : 我有以下perl搜索和替换:

With 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 

Without 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 

My objective is to replace onclick="img=document.getElementById('img_1'); img.style.display = (img.style.display == 'none' ? 'block' : 'none');return false" with nothing in the file test.html . 我的目标是将onclick="img=document.getElementById('img_1'); img.style.display = (img.style.display == 'none' ? 'block' : 'none');return false"替换为文件test.html没有任何内容。 What am I messing up? 我搞砸了吗?

I keep on getting the error : -sh: syntax error near unexpected token )'` which I cannot help but feel is because of some stupid escaping on my part. 我继续收到错误消息: -sh: syntax error near unexpected token )'`我不禁感到是由于我的一些愚蠢的转义。 Please help me out. 请帮帮我。

[ You didn't specify for which shell you are building the command. [您没有指定要为哪个shell构建命令。 I'm going to assume sh or bash . 我将假设为shbash ] ]


Problem #1: Converting text into a regex pattern 问题1:将文本转换为正则表达式模式

Many characters have a special meaning in regex patterns. 在正则表达式模式中,许多字符都有特殊含义。 Among those you used, ( , ) , . 在您使用过的(). and ? ? are special. 很特别 These need to be escaped. 这些需要逃脱。

If you want to match 如果你想匹配

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

You need to use the pattern 您需要使用模式

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

So your Perl code is 所以你的Perl代码是

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

Problem #2: Converting text (a Perl program) into a shell literal 问题2:将文本(Perl程序)转换为Shell文字

This is the problem you asked about. 这是您所问的问题。

Sections quoted by single quotes (" ' ") end at the next single quote (unconditionally), so the following is wrong: 用单引号(“ ' ”)引起的部分以下一个单引号结尾(无条件),因此以下错误:

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

If you wanted to output " foo'bar ", you could use 如果要输出“ foo'bar ”,则可以使用

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

foo and bar are quoted by single quotes, and the single quote is escaped using \\ . foobar用单引号引起来,并且单引号使用\\转义。 \\ works here because it's outside of single quotes. \\之所以在这里工作是因为它在单引号之外。

So, the lesson is basically use '\\'' instead of ' inside single quotes. 因此,本课基本上在单引号内使用'\\''代替'

you want to pass the following program to Perl: 您要将以下程序传递给Perl:

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

To do so, you'll need to create a shell literal that produces the correct argument, meaning we want to surround the whole with single quotes and escape the existing single quotes. 为此,您需要创建一个生成正确参数的shell文字,这意味着我们要用单引号将整个内容括起来,并转义现有的单引号。 We get the following: 我们得到以下内容:

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

As such, the entire command would be 这样,整个命令将是

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

Using the next: 使用下一个:

perl -lnE 'say quotemeta $_'

and feed it with your plain input: 并用您的普通输入来输入:

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

you will get: 你会得到:

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

So using it: 因此,使用它:

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

should work. 应该管用。

Some things are easier when you don't use a one-liner. 当您不使用单线时,某些事情会更容易。 Less things to escape, and not as fragile. 逃脱的东西更少,而不是那么脆弱。

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;
}

Then execute the script: 然后执行脚本:

perl -i thescript.pl test.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM