如何在Perl单行中转义特殊字符以进行替换?

yae*_*ael 15 perl

是否有某种方式来替换字符串,如@*?&不需要在前面加上一个"\"?

例:

perl -pe 'next if /^#/; s/\@d\&/new_value/ if /param5/' test
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我需要替换一个@d&with new_value但旧值可能包含任何字符,如何只转义需要转义的字符?

Eth*_*her 11

正如perldoc perlre所讨论的那样:

...今天更常见的是使用quotemeta()函数或"\ Q"metaquoting转义序列来禁用所有元字符的特殊含义,如下所示:

/$unquoted\Q$quoted\E$unquoted/
Run Code Online (Sandbox Code Playgroud)

请注意,如果在"\ Q"和"\ E"之间放置文字反斜杠(那些不在插值变量内),双引号反斜杠插值可能会导致混乱的结果.如果你需要在"\ Q ...\E"中使用文字反斜杠,请参阅perlop中的"解析引用结构的Gory细节".

您还可以'在s ///操作中使用a 作为分隔符,以便按字面解析所有内容:

my $text = '@';
$text =~ s'@'1';
print $text;
Run Code Online (Sandbox Code Playgroud)

在您的示例中,您可以执行(注意单引号):

perl -pe 's/\b\Q@f&\E\b/new_value/g if m/param5/ and not /^ *#/'
Run Code Online (Sandbox Code Playgroud)


Cha*_*ens 10

你有几个问题:

  1. 您使用\b不当
  2. 您正在用shell变量替换代码
  3. 您需要引用元字符

perldoc perlre

字边界("\ b")是两个字符之间的一个点,在其一侧有一个"\ w"

无论是人物@还是&\w字符.所以你的比赛肯定会失败.你可能想要使用类似的东西s/(^|\s)\@d\&(\s|$)/${1}new text$2/

(^|\s)说要匹配string(^)的开头或空格字符(\s).

(\s|$)说要匹配string($)的末尾或空格字符(\s).

要解决第二个问题,你应该使用%ENV.

要解决第三个问题,您应该使用\Q\E转义序列来转义值$ENV{a}.

总而言之,我们得到:

#!/bin/bash

export a='@d&'
export b='new text'

echo 'param5 @d&' | 
    perl -pe 'next if /^#/; s/(^|\s)\Q$ENV{a}\E(\s|$)/$1$ENV{b}$2/ if /param5/' 
Run Code Online (Sandbox Code Playgroud)

哪个打印

param5 new text
Run Code Online (Sandbox Code Playgroud)


Sch*_*ern 6

其他答案已经涵盖了这个问题,现在这里是你的元问题:倾斜牙签综合征.当分隔符和逃逸开始模糊时:

s/\/foo\/bar\\/\/bar\/baz/
Run Code Online (Sandbox Code Playgroud)

解决方案是使用不同的分隔符.您几乎可以使用任何东西,但平衡的牙箍效果最佳.大多数编辑都可以解析它们,您通常不必担心转义.

s{/foo/bar\\}{/bar/baz}
Run Code Online (Sandbox Code Playgroud)

这是你的带有支撑分隔符的正则表达式.

s{\@d\&}{new_value}
Run Code Online (Sandbox Code Playgroud)

眼孔更容易.