簡體   English   中英

如何將字符串中哈希的所有鍵替換為其值?

[英]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,請改用該方法。 您甚至可以使用sprintfprintf完成工作:

  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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM