如何在 perl 中将字符串转换为哈希表



我有一个来自for循环的字符串:

@file = "/path/window/*_testing_42.csv";

foreach $file(@file) {

$name = $file=~ /(w*)_testing_42/; #comes from file path
$name = 1$;
print $name; #prints G43B76P90T45
}

这个字符串中有 4 个我需要的值(G43、B76、P90、T45(。我想将它们放入哈希中,以便我可以专门引用每个值。但是,我尝试实现的哈希表代码不适用于我的预期目的:

my %hash;

foreach $file(@file) {

$name = $file=~ /(w*)_testing_42/; #comes from file path
$name = 1$;
print $name; #prints G43B76P90T45

my($first $second $third $fourth) = $name;
$hash{"first"} = $first;
$hash{"second"} = $second;
$hash{"third"} = $third;
$hash{"fourth"} = $fourth;

预期输出:

print $fourth; #should print T45

print $first; #should print G43
print $third #should print  P90
}

首先,您需要将名称分为 4 个部分:

my ($first, $second, $third, $fourth) = unpack("(A3)*", $name);

填充哈希

$hash{"first"} = $first;
$hash{"second"} = $second;
$hash{"third"} = $third;
$hash{"fourth"} = $fourth;

并打印哈希

print $hash{"fourth"};

如果我正确理解你想做什么,那么@Gever的答案应该可以解决问题。 这是使用正则表达式而不是解压缩的替代实现:

use 5.010;
use strict;
use warnings;
my @file = glob("/path/window/*_testing_42.csv");
foreach my $file (@file) {
my($name) = $file =~ /(w+)_testing_42/;
my @code = $name =~ /(...)/g;
say 'Parts found: ', scalar(@code);   # Parts found: 4
say $code[0];   # G43
say $code[1];   # B76
say $code[2];   # P90
say $code[3];   # T45
}

我使用了数组而不是哈希,因为这对我来说更有意义,但如果你真的想要一个哈希,你可以这样做:

foreach my $file (@file) {
my($name) = $file =~ /(w+)_testing_42/;
my %hash;
@hash{'first', 'second', 'third', 'fourth'} = $name =~ /(...)/g;
say $hash{first};   # G43
say $hash{second};  # B76
say $hash{third};   # P90
say $hash{fourth};  # T45
}

在这一行中:

my($name) = $file =~ /(w+)_testing_42/;

$name周围的括号很重要,因为它们强制在列表上下文中评估匹配项,这将返回在(w+)中捕获的正则表达式部分。 如果没有括号,值 1 将分配给$name,因为有 1 个匹配项。

将值列表分配给哈希中的一系列键(称为"哈希片"(的语法有些令人困惑。 Perl 知道我们正在将值分配给%hash,因为变量名称后面有{,但我们在变量名称前放置了一个@,以表示我们正在为哈希切片分配多个值。 在变量名称前使用$表示我们正在分配给哈希中的单个值。

我从您的代码中更改的另一件事是我在循环中声明了%hash。 这意味着您只能在循环中引用它。 如果在循环外部声明它,则在处理每个匹配的文件名后,将保留一组值,但哈希可能包含来自不同文件名的值,具体取决于上次迭代中存在的字段数。

最新更新