perl YAML :: Tiny在哈希散列中搜索第二级值

时间:2014-06-06 07:43:31

标签: perl hash yaml

我在YAML :: Tiny对象中有哈希值哈希,如

        $yaml = YAML::Tiny->read_string($config);

现在,我正在尝试检查哈希哈希值中的特定值,如果值匹配,请按

键。
        foreach my $key (keys %{$yaml->[0]}){
               if ( values %{$yaml->[0]->{$key}} =~ /My_String/){
                   print $key;
               }

但它正在给予

Applying pattern match (m//) to %hash will act on scalar(%hash) at script.pl line 25.
Type of argument to keys on reference must be unblessed hashref or arrayref at script.pl line 25.

我想这是因为值%{$ yaml-> [0] - > {$ key}也返回一个哈希值,因为该对象本身是哈希的哈希值。我在这里做错了什么?

测试数据::

'string_1' => {
                      'test_data' => 82,
                      'test_data1' => 99,
                      'test_data2' => My_string
                    },
'string_2' => {
                     'test_data3' => 97,
                     'test_data4' => 67
                   }
    };

我正在寻找打印test_data2,因为它的值是My_string

2 个答案:

答案 0 :(得分:1)

有两个问题。

  1. 优先顺序:Perl将表达式理解为values( %{...} =~ /.../ )

    $ perl -MO=Deparse,-p -e 'values %{ {a=>3} } =~ /x/'
    values((%{+{'a', 3};} =~ /x/));
    
  2. 即使在修复之后:绑定操作符也可以用在标量(字符串)上。 values返回一个列表。你究竟想做什么?

  3. 更新:以下脚本可以满足您的需求,同时仍然尝试保留您的逻辑,即用grep替换内部for循环。

    #!/usr/bin/perl
    use warnings;
    use strict;
    
    my $yaml = [{
                'string_1' => {
                               'test_data' => 82,
                               'test_data1' => 99,
                               'test_data2' => 'My_String'
                              },
                'string_2' => {
                               'test_data3' => 97,
                               'test_data4' => 67
                              }
               }];
    
    for my $key (keys %{$yaml->[0]}){
        if (my @matches = grep $yaml->[0]{$key}{$_} =~ /My_String/,
                          keys %{ $yaml->[0]->{$key} }
           ){
            print "$key: @matches\n";
        }
    }
    

答案 1 :(得分:1)

如果您的结构是散列哈希,那么您需要显式遍历您的数据:

use strict;
use warnings;

use YAML;

my $hashref = Load(<<'END_YAML');
---
string_1:
  test_data: 82
  test_data1: 99
  test_data2: My_string
string_2:
  test_data3: 97
  test_data4: 67
END_YAML

SEARCH:
while (my ($k1, $v1) = each %$hashref) {
    while (my ($k2, $v2) = each %$v1) {
        if ($v2 =~ /My_string/) {
            print "$k1 -> $k2 -> $v2\n";
            last SEARCH;
        }
    }
}

输出:

string_1 -> test_data2 -> My_string