Работа с несколькими группами захвата в нескольких записях
Формат данных:
attribname: data
Пример данных:
cheese: good
pizza: good
bagel: good
fire: bad
Код:
my $subFilter='(.+?): (.+)';
my @attrib = ($dataSet=~/$subFilter/g);
for (@attrib)
{
print "$_\n";
}
Код выплевывает:
cheese
good
pizza
good
[etc...]
Мне было интересно, что это за легкий способ Перли? Я анализирую данные из журнала, данные выше - мусор для простоты. Я новичок в Perl, я подозреваю, что мог бы сделать это через фанатские индексы, но мне было интересно, есть ли короткий способ реализации этого? Есть ли способ поместить группы захвата в две разные переменные вместо последовательного добавления в список вместе со всеми совпадениями?
Изменить: я хочу атрибут и его связанное значение вместе, чтобы я мог делать с ними то, что мне нужно. Например, если внутри моего цикла for я могу получить доступ как к имени атрибута, так и к значению атрибута.
Редактировать:
Я старался
my %attribs;
while (my $line = <$data>)
{
my ($attrib, $value) = ($line=~m/$subFilter/);
print $attribs{$attrib}," : ", $value,"\n";
}
и не повезло:(Я не получаю никакого вывода с этим. Мои данные находятся в переменной, а не в файле, потому что они проанализированы из набора родительских данных, которые находятся в файле. Было бы удобно, если бы моя переменная работала чтобы my (@attrib, @value) = ($line=~/$subFilter/g);
заполнены списки соответствующим образом с несколькими совпадениями.
Решение:
my @line = ($7 =~/(.+?)\n/g);
for (@line)
{
my ($attrib, $value) = ($_=~m/$subFilter/);
if ($attrib ne "")
{
print $attrib," : ", $value,"\n";
}
}
2 ответа
Я не совсем понимаю, что вы на самом деле хотите хранить, но вот как вы можете хранить данные в хэш-таблице, где "1" означает "хорошо", а "0" - "плохо":
use strict;
use warnings;
use Data::Dumper;
my %foods;
while (my $line = <DATA>)
{
chomp $line;
my ($food, $good) = ($line =~ m/^(.+?): (.+)$/);
$foods{$food} = ($good eq 'good' ? 1 : 0);
}
print Dumper(\%foods);
__DATA__
cheese: good
pizza: good
bagel: good
fire: bad
Это печатает:
$VAR1 = {
'bagel' => 1,
'cheese' => 1,
'fire' => 0,
'pizza' => 1
};
Разумным подходом будет использование split
функция:
my %attrib;
open my $data, '<', 'fileName' or die "Unable to open file: $!";
while ( my $line = <$data> ) {
my ( $attrib, $value ) = split /:\s*/, $line, 2;
$attrib{$attrib} = $value;
}
close $data;
foreach my $attrib ( keys %attrib ) {
print "$attrib: $attrib{$attrib}\n";
}
Если вы в однострочнике, то следующее достигнет того же:
$ perl -F/:\s*/ -ane '$attrib{$F[0]} = $F[1]; } END { print $_,"\t",$attrib{$_},"\n" foreach keys %attrib;" fileName