[英]How can I replace all keys of a hash in a string with their values?
我正在用可變系統編碼腳本。 該程序為每個關鍵字使用一個帶有值的哈希,但是當替換字符串中的所有關鍵字時,我不知道如何繼續。
替換代碼如下:
while ( ($key, $value) = each %variables_hash ) {
if ( -1 != index($CMD, $key) ) {
# Here should be the code that I cant think how to do
}
}
$CMD
是輸入字符串, %variables_hash
是包含變量的哈希
您可以使用substr替換子字符串。 我用while
代替if
來代替多次出現。 length $key
用於確定要替換的子字符串的長度。
#!/usr/bin/perl
use warnings;
use strict;
my %variables_hash = (
_number => 123,
_name => 'John Smith',
);
my $CMD = 'INSERT INTO customers (name, code) VALUES("_name", _number)';
while (my ($key, $value) = each %variables_hash) {
while (-1 != ( my $pos = index $CMD, $key )) {
substr $CMD, $pos, length $key, $value;
}
}
print $CMD, "\n";
另一種選擇是使用替換(請參閱perlop )或模板(例如Template )。
my $regex = join '|', map quotemeta, keys %variables_hash;
$CMD =~ s/($regex)/$variables_hash{$1}/g;
請注意,如果一個變量名是另一個變量的子串,則可能要從最長到最短進行處理( substr
解決方案也是如此); 所以你可能需要說
map quotemeta, sort { length $b <=> length $a } keys %variables_hash;
需要注意的是變量不能用下划線開始,但他們沒有必要,因為這些變量都包含在模板標簽,這樣你就不會意外地取代name
時,它指的是列名。
use Template;
my %variables_hash = (
number => 123,
name => 'John Smith',
);
my $CMD = 'INSERT INTO customers (name, code) VALUES("[% name %]", [% number %])';
my $template = 'Template'->new;
$template->process(\$CMD, \%variables_hash);
如果您要成為Perl程序員,那么您需要閱讀Perl FAQ。 這是來自perlfaq4。
如何擴展文本字符串中的變量?
(由brian d foy貢獻)
如果可以避免,請不要這樣做,或者可以使用模板系統,例如Text :: Template或Template Toolkit,請改用該方法。 您甚至可以使用
sprintf
或printf
完成工作:my $string = sprintf 'Say hello to %s and %s', $foo, $bar;
但是,對於一次性的簡單情況,我不想使用完整的模板系統,我將使用其中包含兩個Perl標量變量的字符串。 在此示例中,我想將
$foo
和$bar
擴展為其變量的值:my $foo = 'Fred'; my $bar = 'Barney'; $string = 'Say hello to $foo and $bar';
我做到這一點的一種方法涉及替換運算符和double
/e
標志。 第一個/e
在替換端求值$1
,並將其轉換為$foo
。 第二個/e
以$foo
開頭,並將其替換為它的值。 然后,$foo
變成'Fred',最后就是字符串中剩下的:$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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.