Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 如何替换字符串中的非简单变量引用_Perl - Fatal编程技术网

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"/;