2017-02-10 67 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;