我有一个来自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
}
答案 0 :(得分:1)
首先,您需要将名称分为4部分:
my ($first, $second, $third, $fourth) = unpack("(A3)*", $name);
填充哈希
$hash{"first"} = $first;
$hash{"second"} = $second;
$hash{"third"} = $third;
$hash{"fourth"} = $fourth;
并打印哈希
print $hash{"fourth"};
答案 1 :(得分:1)
如果我正确理解您要执行的操作,那么@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
。
在哈希(称为“哈希切片”)中为一系列键分配值列表的语法有些混乱。 Perl知道我们正在为%hash
分配值,因为变量名之后是{
,但是我们在变量名之前加上了@
,以表示我们正在为哈希分配多个值切片。在变量名称前使用$
表示我们正在将哈希值分配给单个值。
我对您的代码所做的另一件事是,我在循环内声明了%hash
。这意味着您只能在循环内引用它。如果在循环外声明它,则一组值将在处理每个匹配的文件名后保留,但是散列可能包含来自不同文件名的值,具体取决于上次迭代中存在多少个字段。