所以我想知道是否有更好的方法来做到以下几点:
我有一系列线要多次打印出来,每次都要换一些不同的东西。例如:
my @array = ("I like most animals.\n", "Most animals like me.\n");
my @animals = ("dogs", "cats");
foreach my $animal (@animals) {
foreach my $sentence (@array) {
$sentence =~ s/animals/$animal/g;
print $sentence;
}
}
这个问题仅在第一次起作用,因为动物在原始阵列中被替换。为了绕过我的for循环,我只需执行类似my $line = $sentence;
的操作,然后只使用正则表达式并打印$ line。有没有更好的方法呢?
答案 0 :(得分:4)
较新的perls中的r
标志可以提供帮助(5.14以后)
问题是 - 如果你在$sentence
上执行“sed样式”模式替换它是数组元素的别名,而不是它本身的变量。
这是因为数组迭代器的工作原理 - 它允许你修改循环中的元素,并让它更新原始元素:
foreach my $value ( @list_of_things ) {
$value++;
}
将改变@list_of_things
。这实际上是您的模式替换正在做的事情。我们需要在执行此操作之前复制它,因此我们可以保留原始文件 - 或使用r
标记 - 以避免发生这种情况。
所以最简单的方法是:
#!/usr/bin/perl
use warnings;
use strict;
my @array = ("I like most animals.\n", "Most animals like me.\n");
my @animals = ("dogs", "cats");
foreach my $animal (@animals) {
foreach my $sentence (@array) {
print $sentence=~ s/animals/$animal/r;
}
}
你也可能失去g
,因为它似乎是多余的。
输出:
I like most dogs.
Most dogs like me.
I like most cats.
Most cats like me.
但你实际上根本不需要$sentence
:
foreach my $animal (@animals) {
for (@array) {
print s/animals/$animal/r;
}
}
在较旧的perls中,作为choroba注释 - 您可以通过将别名复制到局部变量来执行相同的操作:
(my $s = $sentence) =~ s/animals/$animal/g;
print $s;
答案 1 :(得分:1)
您要找的是一个模板。以下是使用Template的示例:
#!/usr/bin/perl
use warnings;
use strict;
use Template;
my @array = ( "I like most [% animals %].\n",
"Most [% animals %] like me.\n",
);
my @animals = qw( dogs cats );
my $template = 'Template'->new;
for my $animal (@animals) {
for my $sentence (@array) {
$template->process(\$sentence, { animals => $animal });
}
}