是否有某种方式来替换字符串,如@或*或?或&不需要在前面加上一个"\"?
例:
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
你有几个问题:
\b不当字边界("\ 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)
其他答案已经涵盖了这个问题,现在这里是你的元问题:倾斜牙签综合征.当分隔符和逃逸开始模糊时:
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)
眼孔更容易.