2008-11-21 61 views
7

我正在寫一個可能被用戶修改的腳本。目前我將配置設置存儲在腳本中。它以哈希散列的形式存在。如何更改散列鍵的大小寫?

我想防止人們不小心在散列鍵中使用小寫字母,因爲這會破壞我的腳本。

檢查散列鍵並僅針對小寫字母的任何鍵發出警告很簡單,但我寧願自動修復大小寫。

換句話說,我想將頂級哈希中的所有哈希鍵都轉換爲大寫。

回答

13

安迪的回答是一個很好的答案,但他uc小號每一個鍵,然後再uc的IT,如果它不匹配。

uc的IT一次:

%hash = map { uc $_ => $hash{$_} } keys %hash; 

但既然你說用戶存儲密鑰的,平局是一個更可靠的方法,即使慢。

package UCaseHash; 
require Tie::Hash; 

our @ISA = qw<Tie::StdHash>; 

sub FETCH { 
    my ($self, $key) = @_; 
    return $self->{ uc $key }; 
} 

sub STORE { 
    my ($self, $key, $value) = @_; 
    $self->{ uc $key } = $value; 
} 

1; 

然後在主:

tie my %hash, 'UCaseHash'; 

這是一個秀。 「魔術」封裝了它,所以用戶不會在不知不覺中混淆它。

當然,只要您使用的是「階級」,你可以通過在配置文件名稱,並從那裏初始化:

package UCaseHash; 
use Tie::Hash; 
use Carp qw<croak>; 

... 

sub TIEHASH { 
    my ($class_name, $config_file_path) = @_; 
    my $self = $class_name->SUPER::TIEHASH; 
    open my $fh, '<', $config_file_path 
     or croak "Could not open config file $config_file_path!" 
     ; 
    my %phash = _process_config_lines(<$fh>); 
    close $fh; 
    $self->STORE($_, $phash{$_}) foreach keys %phash; 
    return $self; 
} 

在那裏你將不得不這樣稱呼它:

tie my %hash, 'UCaseHash', CONFIG_FILE_PATH; 

...假設一些常數CONFIG_FILE_PATH

+1

你知道,有CPAN上一個模塊,做到這一點。無需自己編寫代碼:Hash :: Case,請參閱http://search.cpan.org/dist/Hash-Case/ – bart 2008-11-21 22:28:17

13

遍歷散列並用大寫字母替換所有小寫字母,然後刪除舊的小寫字母。大致爲:

for my $key (grep { uc($_) ne $_ } keys %hash) { 
    my $newkey = uc $key; 
    $hash{$newkey} = delete $hash{$key}; 
} 
0

這將轉換的多層次哈希爲小寫

my $lowercaseghash = convertmaptolowercase(\%hash); 

sub convertmaptolowercase(){ 
    my $output=$_[0]; 
    while(my($key,$value) = each(%$output)){ 
     my $ref; 
     if(ref($value) eq "HASH"){ 
      $ref=convertmaptolowercase($value); 
     } else { 
      $ref=$value; 
     } 
     delete $output->{$key}; #Removing the existing key 
     $key = lc $key; 
     $output->{$key}=$ref; #Adding new key 
    } 
    return $output; 
}