Если я правильно понимаю, что вы пытаетесь сделать, то ответ @ 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
внутри цикла.Это означает, что вы можете ссылаться на него только внутри цикла.Если вы объявите его вне цикла, один набор значений будет сохраняться после обработки каждого соответствующего имени файла, но хэш может содержать значения из разных имен файлов в зависимости от того, сколько полей присутствовало на последних итерациях.