Perl 如何替换字符串中的非简单变量引用
考虑以下代码:Perl 如何替换字符串中的非简单变量引用,perl,Perl,考虑以下代码: my $msg='My name is $person->{name}.'; my $person={ name=>'Peter', gender=>'Male' }; 所以我想打印$msg。我看到过解决简单变量替换的例子,比如“$name”,但我没有看到如何解决我的问题。我试过: print eval $msg; 但这不起作用(什么也没印出来)。如何打印我的名字是Peter。?当您首先声明散列时,它会起作用。 请确保使用双引号: my $person={
my $msg='My name is $person->{name}.';
my $person={ name=>'Peter', gender=>'Male' };
所以我想打印$msg。我看到过解决简单变量替换的例子,比如“$name”,但我没有看到如何解决我的问题。我试过:
print eval $msg;
但这不起作用(什么也没印出来)。如何打印
我的名字是Peter。
?当您首先声明散列时,它会起作用。
请确保使用双引号:
my $person={ name=>'Peter', gender=>'Male' };
my $msg="My name is $person->{name}.";
print $msg;
你正在发明一个模板系统。幸运的是,它已经存在: 当
eval
“不工作”时,它设置特殊变量$@
,并在计算表达式时遇到Perl错误。在你的情况下,这个信息是
syntax error at (eval 1) line 2, at EOF
因为文字
My name is $person->{name}.
无法将其解析为Perl代码。但一个简单的解决办法是用引号将文本括起来
my $msg='"My name is $person->{name}."';
my $person={ name=>'Peter', gender=>'Male' };
print eval $msg;
输出:
My name is Peter.
修复此程序的其他方法是将引用的文本发送到eval
:
my $msg='My name is $person->{name}.';
print eval "\"$msg\"";
print eval qq/"$msg"/;
对于这样的问题,总是值得查看Perl常见问题解答
对不起,也许我原来的问题不清楚。$msg的值没有设置为字符串常量-这就是为什么我将文本括在单引号字符中的原因。消息需要在使用时进行评估,而不是在分配字符串时。是的,我知道。我真的试图理解是否有一种方法可以使用实际的perl语法指定替换。有,但只有在创建双引号字符串时变量已经存在的情况下。否则,您谈论的是模板化,应该使用模板化模块。还有一些其他的选择:,啊,但是还有eval-现在,多亏了@mob,我现在知道为什么它对我不起作用了。不过,感谢您给我指出Text::Template,也许有一天它会有用。我要补充一点,string eval是个坏主意,输入变量至少应该通过quotemeta传递。这就是我想要的。感谢您提供有关存储错误的信息。非常有用。@Grinnz:有趣的是,
$person
可以包含任何内容,并且仍然是安全的<另一方面,code>$msg是危险的。具体来说,为什么这是个坏主意,$msg='@{[system rm~/.bashrc]}'代码>这很危险。我举的例子是对我实际尝试做的事情的简化。请放心,$msg
字符串不会从用户输入(或任何其他不受控制的数据)中派生。当然是这样。但在本例中,我提供了答案,但它没有提供答案。@pdac:但它提供了答案。我链接的问题正好提供了你需要的信息。我不这么认为(除非我遗漏了什么)。这说明了如何使用正则表达式替换来计算简单名称,如$name
,而不是如何处理散列引用,如$person->{name}
。该方法还将破坏我的原始模板。这里的解决方案是使用eval
。@pdac:FAQ中的第二个示例使用哈希。将其转换为散列引用是一个微不足道的语法更改。您可以通过复制原始变量或使用替换运算符上的/r
选项来停止销毁原始变量。这种方法比使用eval
安全得多。
my $msg='My name is $person->{name}.';
print eval "\"$msg\"";
print eval qq/"$msg"/;