Работа с несколькими группами захвата в нескольких записях

Формат данных:

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
Другие вопросы по тегам