如何在perl中插入存储在变量中的转义字符?

时间:2016-05-20 10:50:21

标签: perl

我编写了一个perl代码来获取源文件名,目标文件名,模式和替换字符串。下面是我编写的代码。

chomp($input=<stdin>);   #source file name.
open SRC, $input;        #opening the file .

chomp($input=<stdin>);   #destination file name.
open DES, ">>$input";     #opening the file.

chomp($pattern=<stdin>);   #pattern to be matched.

chomp($replace=<stdin>);   #replacement string.

while(<SRC>){
    s/$pattern/$replace/g;
    print DES $_;
}

我编写了这段代码来替换文件中的特定值并将其存储在另一个文件中。根据代码,如果我将模式“”(空格)和替换字符串赋予\ n,它应该给出如下输出。

示例输入

Hai hello this for testing .

示例输出

Hai 
hello
this
for
testing
.

但它的输出结果如下。

输出

hai\nhello\nthis\nis\nfor\ntesting\n.

请帮我解决这个问题。

2 个答案:

答案 0 :(得分:7)

总是 use strictuse warnings 'all'在您编写的每个Perl程序的顶部,结束用my声明每个变量。您还应该使用词法文件句柄和open的三参数形式,并且始终检查对open的调用是否成功。所以

open DES, ">>$input"

应该更像

open my $des_fh, '>>', $input or die qq{Unable to open "$input" for appending: $!}


您可以使用eval,但使用String::Interpolate模块会更清晰,更安全,该模块可以访问处理双引号字符串的perl中的代码。它导出interpolate函数,该函数将正确转换所有变量引用以及\n\t等任何特殊字符

看起来像这样

use strict;
use warnings 'all';

use String::Interpolate 'interpolate';

chomp( my $in_file = <> );
open my $in_fh, '<', $in_file or die qq{Unable to open "$in_file" for input: $!};

chomp( my $out_file = <> );
open my $out_fh, '>>', $out_file or die qq{Unable to open "$out_file" for input: $!};

chomp( my $pattern = <> );

chomp( my $replace = <> );
$replace = interpolate($replace);

while ( <$in_fh> ) {
    s/$pattern/$replace/g;
    print $out_fh $_;
}

请注意,您可以在命令行中输入参数,而不是让程序提示

use strict;
use warnings 'all';

use String::Interpolate 'interpolate';

my $pattern = shift;
my $replace = shift;
$replace = interpolate($replace);

print s/$pattern/$replace/gr while <>;

你会这样称呼

$ perl replace.pl ' '  '\n'  sample.txt

您可以按正常方式将输出重定向到文件

$ perl replace.pl ' '  '\n'  sample.txt > output.txt

答案 1 :(得分:1)

我强烈推荐String::Substitution提供的功能。

替换

use String::Substitution qw( gsub_modify );

gsub_modify($_, $pattern, $replace);

\n

这不仅仅处理$1;它也会处理eval EXPR

注意:

  • 使用/ee(有时伪装成<a href="#" class="button button-block" ng-click="register()">Registrarse</a> )有很多建议,但这很容易出错并且很危险。

  • 过去,我提供了使用String :: Interpolate的解决方案,但该模块提供了一个非常奇怪的界面。