簡體   English   中英

不區分大小寫的哈希鍵perl

[英]Case insensitive hash keys perl

問題

我有一個哈希/數組結構,但是有些哈希鍵不在同一情況下。

我想知道是否有一種無需手動檢查每個哈希鍵就可以處理這種情況的方法。

在下面的示例中,我希望打印所有ID / iD / id / Id字段。


范例程式碼

use warnings;
use strict;


my $Hash = {
   Server  =>   [
                        {
                                Id=>123
                        },
                        {
                                iD=>456
                        },
                        {
                                ID=>789
                        }
                ]

};

for (@{$Hash->{Server}}){
        print "$_->{ID}\n"
        #This is the problematic part
}

其他

Perl版本 :v5.10.0

該數據是從其他地方接收到的,必須保持相同的大小寫,上面的示例很小,我不能簡單地將它們全部更改為相同的大小寫。

需要更多信息請告訴我。

好吧,這取決於您的信息來源。 看起來您已經解析了某些內容,因此可能會有更好的解決方案。

但是,有了這里,我會這樣做:

for my $entry (@{$Hash->{Server}}){
   #grep, find first match. Dupes discarded. 
   my ( $key ) = grep { /^id$/i } keys %$entry; 
   print "$key => ",$entry -> {$key},"\n";
}

這可以通過將grepi regex結合使用來實現,以使keys不區分大小寫,並搶占先出現的內容。 因此,如果您對/id/i有多個匹配項,那么獲得哪個匹配項將是隨機的。 (雖然sort可能會有所幫助)

鑒於您正在使用XML ,我可能會稍微回溯一下,扔掉XML::Simple並改為這樣做:

#!/usr/bin/perl
use strict;
use warnings;

use XML::Twig;

my $twig = XML::Twig -> new ( twig_handlers => { '_all_' => sub { $_ -> lc_attnames }} );
   $twig -> parse ( \*DATA );

print "XML looks like:\n";
$twig -> set_pretty_print ( 'indented_a'); 
$twig -> print;

print "Output:\n";

foreach my $server ( $twig -> get_xpath('//Server') ) { 
    print $server -> att('id'),"\n";
}

__DATA__
<XML>
   <Server ID="123" />
   <Server Id="456" />
   <Server id="789" />
</XML>

或者,您可以:

foreach my $server ( $twig -> get_xpath('//Server') ) {
    $server -> lc_attnames;
    print $server -> att('id'),"\n";
}

代替在樹枝處理程序中執行此操作。 第一個答案將“修復”您所有的XML,使其具有小寫屬性,而這可能不是您想要的。 但是,這可能對其他情況很有用,這就是為什么我給出了兩個示例。

沒有內置的方法可以做到這一點。 你可以做的是使用名單::的Util的first至少獲得較少的檢查,然后仍然嘗試,直到一個適合的每個鍵。

use strict;
use warnings;
use feature 'say';
use List::Util 'first';

my $Hash = {
    Server => [
        {
            Id => 123
        },
        {
            iD => 456
        },
        {
            ID => 789
        }
    ]
};

foreach my $thing ( @{ $Hash->{Server} } ) {

    #                     this returns the first match in the list, like grep   
    #   so we need to use it here to return the actual value
    say $thing->{ first { $thing->{$_} } qw/id ID iD Id/ };
}

如果數據結構中還有許多其他鍵,則這比查看所有鍵便宜,因為您最多只能查找所有可能的id鍵加一個,最好最多兩個。

如果要自動生成可能的密鑰列表,並且可以任意混合使用大寫和小寫字母,請查看此答案

我建議您使用正則表達式忽略使用i標志的鍵大小寫。

for my $item ( @ { $Hash->{Server} }) {
    for(keys %{$item}) {
        print $item -> {$_},"\n" if /^ID$/i;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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