我正在尝试在替换字符串中使用变量插值,包括$1
,$2
,...
但是,我无法将其$1
扩展为替换版。我最终会有
可以从配置文件中读取$pattern
和$replacement
个变量,但是甚至可以
手动设置它们不起作用。
在示例脚本中,您可以看到$1
(应该是'DEF')不是
在$new_name
中展开,但它位于$new_name2
(没有变量)。
在替换中添加“e”标志无济于事。
我该如何解决这个问题?
马特
示例代码:
#!/usr/local/bin/perl
use strict;
my $old_name = 'ABC_DEF_GHI';
my $pattern = 'ABC_(...)_GHI';
my $replacement = 'CBA_${1}_IHG';
# using variables - doesn't work
my $new_name = $old_name;
$new_name =~ s|$pattern|$replacement|;
printf("%s --> %s\n", $old_name, $new_name);
# not using variables - does work
my $new_name2 = $old_name;
$new_name2 =~ s|ABC_(...)_GHI|CBA_${1}_IHG|;
printf("%s --> %s\n", $old_name, $new_name2);
输出:
ABC_DEF_GHI --> CBA_${1}_IHG
ABC_DEF_GHI --> CBA_DEF_IHG
答案 0 :(得分:2)
您需要在代码中进行此更改:
my $replacement = '"CBA_$1_IHG"'; #note the single and double quotes
# ...
$new_name =~ s|$pattern|$replacement|ee; #note the double "ee", double evaluation
See this SO answer了解更多信息
答案 1 :(得分:2)
/e
将$replacement
视为Perl代码。 Perl代码$replacement
只返回它包含的值。
如果您想将$replacement
的内容评估为Perl代码,则需要
s/$search/ my $s = eval $replacement; die $@ if $@; $s /e
可以写成
s/$search/$replacement/ee
请注意,由于$replacement
应包含Perl代码,因此这意味着可以使用它来执行任意Perl代码。
更好的解决方案是意识到您正在编写自己的subpar模板系统,而是使用现有的模板系统。 String::Interpolate了解您当前使用的模板语法:
use String::Interpolate qw( interpolate );
s/$search/interpolate $replace/e