如何在 Perl 中访问哈希数组中的哈希
How to access Hash in Array of Hashes in Perl
我认为我有一个引用哈希数组的哈希。我想了解的是如何访问此哈希数组中的哈希元素。
编辑:这是完整的哈希结构
$VAR1 = {
'CVE-2015-0677' => {
'vuln:references' => [
{
'attr' => {
'reference_type' => 'VENDOR_ADVISORY',
'xml:lang' => 'en'
},
'vuln:source' => 'CISCO',
'vuln:reference' => [
{
'attr' => {
'href' => 'http://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20150408-asa',
'xml:lang' => 'en'
}
}
]
}
],
'vuln:published-datetime' => '2015-04-12T21:59:03.033-04:00',
'vuln:last-modified-datetime' => '2015-04-13T17:45:18.310-04:00',
'vuln:vulnerable-software-list' => [
'cpe:/o:cisco:adaptive_security_appliance_software:9.0.3',
'cpe:/o:cisco:adaptive_security_appliance_software:8.4.5',
],
'vuln:summary' => 'The XML parser in Cisco Adaptive Security Appliance (ASA) Software 8.4 before 8.4(7.28), 8.6 before 8.6(1.17), 9.0 before 9.0(4.33), 9.1 before 9.1(6), 9.2 before 9.2(3.4), and 9.3 before 9.3(3), when Clientless SSL VPN, AnyConnect SSL VPN, or AnyConnect IKEv2 VPN is used, allows remote attackers to cause a denial of service (VPN outage or device reload) via a crafted XML document, aka Bug ID CSCus95290.'
}
};
如果我尝试以下操作,第一个 Data::Dumper 输出的输出与第二个相同。
for my $key ( keys $hash ) {
my @references = $hash->{$key}{'vuln:references'};
print Dumper(@references); #1
for my $vulnref (@references) {
print Dumper($vulnref); #2
}
}
#1
$VAR1 = [
{
'vuln:reference' => 'VENDOR',
'vuln:source' => 'CISCO',
}
];
#2
$VAR1 = [
{
'vuln:reference' => 'VENDOR',
'vuln:source' => 'CISCO',
}
];
所以我的 for 循环似乎没有任何影响?
但是,如果我循环两次,那么第二次循环
for my $key ( keys $hash ) {
my @references = $hash->{$key}{'vuln:references'};
print Dumper(@references); #1
for my $vulnref (@references) {
for my $vuln ($vulnref) {
print Dumper($vuln); #2
}
}
}
#1
$VAR1 = [
{
'vuln:reference' => 'VENDOR',
'vuln:source' => 'CISCO',
}
];
#2
$VAR1 = {
'vuln:reference' => 'VENDOR',
'vuln:source' => 'CISCO',
};
我现在似乎正在访问哈希。
我想我在这里遗漏了一些基本的东西。
非常感谢。
您没有显示哈希的最顶层。你显示的 $VAR1
是 $hash->{key}
的值,但我不知道 key
可能是什么。
总之,用我所拥有的,
$hash->{key}
是对 hash 的引用,其中包含一个键为 vuln:references
[= 的元素92=]
$hash->{key}{'vuln:references'}
是对 数组 的引用,索引为零
$hash->{key}{'vuln:references'}[0]
是对另一个hash的引用,这次有两个个元素
你没有说你想用这些数据做什么,但看起来你只需要
my $data = $hash->{key}{'vuln:references'}[0];
for my $key (keys %$data) {
printf "%s => %s\n", $key, $data->{$key};
}
输出
vuln:source => CISCO
vuln:reference => VENDOR
更新
你没有说 $key
是如何定义的,但是在
for my $data ( $hash->{$key}{'vuln:references'} ) { ... }
您编写了一个循环,该循环执行 一次,$data
设置为我上面描述的数组引用。
要遍历整个结构,假设最外层的散列由 $hash
引用,内部数组是唯一具有多个元素的层,您可以编写
for my $cve ( keys %$hash ) {
my $refs = $hash->{$cve}{'vuln:references'};
print $cve, " \n";
for my $ref ( @$refs ) {
printf " %s => %s\n", $_, $ref->{$_} for keys %$ref;
print "\n";
}
}
请注意 取消引用 keys %$hash
、@$refs
和 %$ref
中的结构。在较新版本的 Perl 中,您可以在不取消引用的情况下使用 keys $hash
,但它是一个实验性功能,不应在实时代码中使用,如果您使用 use warnings
,它将产生一条警告消息正如你应该(与 use strict
一起)在程序的顶部
至于为什么你的代码两次转储相同的值,你有
my @references = $hash->{$key}{'vuln:references'};
将数组 @references
设置为保存 一个元素 ,该元素是当时哈希的数组引用。然后
print Dumper(@references);
逐一转储数组的每个元素。因为只有一个元素,所以它只输出一个转储。终于
for my $vulnref (@references) {
for my $vuln ($vulnref) {
print Dumper($vuln);
}
}
将 $vulnref
设置为 @references
的每个元素。因为只有一个循环执行一次,$vulnref
设置为数组引用。然后 $vuln
被设置为列表的每个元素 ( $vulnref )
所以它需要相同引用的另一个副本。最后该值被转储,结果显示与之前相同的数组引用。
请记住,Perl 标量值以 $
开头;即使数组的一个元素是 $array[0]
,它也被视为 单个值 ,即使该值是一个引用。如果你想访问它引用的数据,你必须使用适当的符号解引用它
我认为我有一个引用哈希数组的哈希。我想了解的是如何访问此哈希数组中的哈希元素。
编辑:这是完整的哈希结构
$VAR1 = {
'CVE-2015-0677' => {
'vuln:references' => [
{
'attr' => {
'reference_type' => 'VENDOR_ADVISORY',
'xml:lang' => 'en'
},
'vuln:source' => 'CISCO',
'vuln:reference' => [
{
'attr' => {
'href' => 'http://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20150408-asa',
'xml:lang' => 'en'
}
}
]
}
],
'vuln:published-datetime' => '2015-04-12T21:59:03.033-04:00',
'vuln:last-modified-datetime' => '2015-04-13T17:45:18.310-04:00',
'vuln:vulnerable-software-list' => [
'cpe:/o:cisco:adaptive_security_appliance_software:9.0.3',
'cpe:/o:cisco:adaptive_security_appliance_software:8.4.5',
],
'vuln:summary' => 'The XML parser in Cisco Adaptive Security Appliance (ASA) Software 8.4 before 8.4(7.28), 8.6 before 8.6(1.17), 9.0 before 9.0(4.33), 9.1 before 9.1(6), 9.2 before 9.2(3.4), and 9.3 before 9.3(3), when Clientless SSL VPN, AnyConnect SSL VPN, or AnyConnect IKEv2 VPN is used, allows remote attackers to cause a denial of service (VPN outage or device reload) via a crafted XML document, aka Bug ID CSCus95290.'
}
};
如果我尝试以下操作,第一个 Data::Dumper 输出的输出与第二个相同。
for my $key ( keys $hash ) {
my @references = $hash->{$key}{'vuln:references'};
print Dumper(@references); #1
for my $vulnref (@references) {
print Dumper($vulnref); #2
}
}
#1
$VAR1 = [
{
'vuln:reference' => 'VENDOR',
'vuln:source' => 'CISCO',
}
];
#2
$VAR1 = [
{
'vuln:reference' => 'VENDOR',
'vuln:source' => 'CISCO',
}
];
所以我的 for 循环似乎没有任何影响?
但是,如果我循环两次,那么第二次循环
for my $key ( keys $hash ) {
my @references = $hash->{$key}{'vuln:references'};
print Dumper(@references); #1
for my $vulnref (@references) {
for my $vuln ($vulnref) {
print Dumper($vuln); #2
}
}
}
#1
$VAR1 = [
{
'vuln:reference' => 'VENDOR',
'vuln:source' => 'CISCO',
}
];
#2
$VAR1 = {
'vuln:reference' => 'VENDOR',
'vuln:source' => 'CISCO',
};
我现在似乎正在访问哈希。
我想我在这里遗漏了一些基本的东西。
非常感谢。
您没有显示哈希的最顶层。你显示的 $VAR1
是 $hash->{key}
的值,但我不知道 key
可能是什么。
总之,用我所拥有的,
[= 的元素92=]$hash->{key}
是对 hash 的引用,其中包含一个键为vuln:references
$hash->{key}{'vuln:references'}
是对 数组 的引用,索引为零$hash->{key}{'vuln:references'}[0]
是对另一个hash的引用,这次有两个个元素
你没有说你想用这些数据做什么,但看起来你只需要
my $data = $hash->{key}{'vuln:references'}[0];
for my $key (keys %$data) {
printf "%s => %s\n", $key, $data->{$key};
}
输出
vuln:source => CISCO
vuln:reference => VENDOR
更新
你没有说 $key
是如何定义的,但是在
for my $data ( $hash->{$key}{'vuln:references'} ) { ... }
您编写了一个循环,该循环执行 一次,$data
设置为我上面描述的数组引用。
要遍历整个结构,假设最外层的散列由 $hash
引用,内部数组是唯一具有多个元素的层,您可以编写
for my $cve ( keys %$hash ) {
my $refs = $hash->{$cve}{'vuln:references'};
print $cve, " \n";
for my $ref ( @$refs ) {
printf " %s => %s\n", $_, $ref->{$_} for keys %$ref;
print "\n";
}
}
请注意 取消引用 keys %$hash
、@$refs
和 %$ref
中的结构。在较新版本的 Perl 中,您可以在不取消引用的情况下使用 keys $hash
,但它是一个实验性功能,不应在实时代码中使用,如果您使用 use warnings
,它将产生一条警告消息正如你应该(与 use strict
一起)在程序的顶部
至于为什么你的代码两次转储相同的值,你有
my @references = $hash->{$key}{'vuln:references'};
将数组 @references
设置为保存 一个元素 ,该元素是当时哈希的数组引用。然后
print Dumper(@references);
逐一转储数组的每个元素。因为只有一个元素,所以它只输出一个转储。终于
for my $vulnref (@references) {
for my $vuln ($vulnref) {
print Dumper($vuln);
}
}
将 $vulnref
设置为 @references
的每个元素。因为只有一个循环执行一次,$vulnref
设置为数组引用。然后 $vuln
被设置为列表的每个元素 ( $vulnref )
所以它需要相同引用的另一个副本。最后该值被转储,结果显示与之前相同的数组引用。
请记住,Perl 标量值以 $
开头;即使数组的一个元素是 $array[0]
,它也被视为 单个值 ,即使该值是一个引用。如果你想访问它引用的数据,你必须使用适当的符号解引用它