2017-02-10 70 views
0

我的代码如下:眼看值

use strict; 

my $store = 'Media Markt'; 
my $sentence = "I visited [store]"; 

# Replace characters "[" and "]" 
$sentence =~ s/\[/\$/g; 
$sentence =~ s/\]//g; 

print $sentence; 

我看到屏幕下面:

笔者走访$店

是否有可能看到以下?我想看看$商店的价值:

我参观的Media Markt

+1

'我$ store ='Media Markt'; my $ sentence =“我去过$商店”; print $ sentence;' – AbhiNickz

+0

另请参阅:http://stackoverflow.com/q/1091634/632407 – jm666

+1

请参阅[当某人回答我的问题时该怎么办?](http://stackoverflow.com/help/someone -answers) – zdim

回答

3

你似乎想用一个字符串,'store'的,以建立一个变量名,$store。这得到symbolic references的主题,并且你do not want to去那里。

做你想做的事情的一种方法是构建一个散列,将这些字符串与相应的变量相关联。然后捕获在句子中括号内的字符串,并通过他们的哈希替换他们重视

use warnings; 
use strict; 

my $store = 'Media Markt'; 
my $time = 'morning'; 

my %repl = (store => $store, time => $time); 

my $sentence = "I visited [store] in the [time]"; 

$sentence =~ s/\[ ([^]]+) \]/$repl{$1}/gex; 

print "$sentence\n"; 

这将输出线I visited Media Markt in the morning

正则表达式捕捉[ ]之间的任何东西,通过使用negated character class[^]](比]其他任何字符) ,匹配一次或多次(+)。然后用它在散列中的值替换它,使用/e来将替换端评估为表达式。由于括号相匹配,他们最终被删除。 /x允许里面的空间,以提高可读性。

对于在括号中找到的每个字符串,散列中必须有一个键值对,否则您将收到警告。考虑到这一点,我们可以提供一个替代

$sentence =~ s{\[ ([^]+) \]}{$repl{$1}//"[$1]"}gex; 

defined-or operator//)放回到"[$1]"如果$repl{$1}回报undef(哈希没有钥匙$1,或者它有undef值)。因此没有哈希对的字符串不变。我将分隔符更改为s{}{},以便可以在里面使用//

这不允许嵌套(如[store [name]]),不处理多行字符串,并具有其他限制。但它应该适用于合理的情况。

+0

如果她考虑动态添加的代码,OP可能只包含一个对象数组。 – Pavel

+0

@paveljurca我完全同意,还有其他的方法来追求似乎是这个想法,并且面向对象的方法会很好。 – zdim

2

正如我在Perl程序员Facebook组织上告诉你的,这与Perl常见问题解答中的一个答案非常相似。

How can I expand variables in text strings?

如果你能避免它,不这样做,或者你可以使用一个模板系统,如文字::模板或模板工具包,这样做吧。你甚至可以把工作与sprintfprintf完成:

my $string = sprintf 'Say hello to %s and %s', $foo, $bar; 

但是,对于一次性简单的情况下,我不希望拿出一个完整的模板系统,我将使用有两个Perl标量变量的字符串。在这个例子中,我想扩大$ foo和$酒吧的变量的值:

my $foo = 'Fred'; 
my $bar = 'Barney'; 
$string = 'Say hello to $foo and $bar'; 

的一种方式,我可以做到这一点涉及到替代运营商和双/e标志。第一个/e在替换端评估$1并将其变为$foo。第二个/e$foo开头,并用其值替换。 $foo,然后,变成“弗雷德”,这是最后什么字符串中左起:

$string =~ s/(\$\w+)/$1/eeg; # 'Say hello to Fred and Barney' 

/e也会忽略这些违规行为的严格,用空字符串替换未定义的变量名。由于我使用的是/e标志(甚至两次!),因此我的字符串形式与eval有相同的安全问题。如果$foo有些奇怪,或许是@{[ system "rm -rf /" ]},那么我可能会陷入麻烦。

为了解决安全问题,我也可以从哈希中提取值而不是评估变量名称。使用单个/e,我可以检查哈希以确保值存在,如果不存在,我可以用标记替换缺失的值,在这种情况下?以通知我错过了什么:

my $string = 'This has $foo and $bar'; 
my %Replacements = (
    foo => 'Fred', 
    ); 
# $string =~ s/\$(\w+)/$Replacements{$1}/g; 
$string =~ s/\$(\w+)/ 
      exists $Replacements{$1} ? $Replacements{$1} : '???' 
      /eg; 
print $string; 

和实际(但真的不建议 - 为的原因在上面的常见问题解释)回答你的问题是:

$sentence =~ s/\[(\w+)]/'$' . $1/ee;