开发者

Dealing with multiple capture groups in multiple records

开发者 https://www.devze.com 2023-01-05 22:27 出处:网络
Data Format: attribname: data Data Example: cheese: good pizza: good bagel: good fire: bad Code: my $subFilter=\'(.+?): (.+)\';

Data Format:

attribname: data

Data Example:

cheese: good
pizza: good
bagel: good
fire: bad

Code:

my $subFilter='(.+?): (.+)';
my @attrib = ($dataSet=~/$subFilter/g);
for (@attrib)
{
   print "$_\n";
}

The code spits out:

cheese
good
pizza
good
[etc...]

I was wondering what an easy Perly way to do this is? I am parsing the data from a log the data above is trash for simplicity. I am newer to Perl, I suspect I could do this via fanangling indexes, but I was wondering if there is a short method of implementing this? Is there any way to have the capture groups put into two different variables instead of serially appended to the list along with all matches?

Edit: I want the attribute and it's associated value together so I can the do what I need to to them. For example if within my for loop I could access both the attribute name and attribute value.

Edit:

I tried

my %attribs;
while (my $line = <$data>)
{
     my ($attrib, $value) = ($line=~m/$subFilter/);
开发者_JS百科     print $attribs{$attrib}," : ", $value,"\n";
}

and no luck :( I don't get any output with this. My data is in a variable not a file, because it parsed out of a set of parent data which is in a file. It would be convenient if the my variable worked so that my (@attrib, @value) = ($line=~/$subFilter/g); filled the lists appropriately with the multiple matches.

Solution:

my @line = ($7 =~/(.+?)\n/g);
for (@line)
{
  my ($attrib, $value) = ($_=~m/$subFilter/);
  if ($attrib ne "")
  {
     print $attrib," : ", $value,"\n";
  }
}


I'm not really clear on what you actually want to store, but here's how you could store the data in a hash table, with '1' indicating good and '0' indicating 'bad':

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

This prints:

$VAR1 = { 
          'bagel' => 1,
          'cheese' => 1,
          'fire' => 0,
          'pizza' => 1
        };


A sensible approach would be to make use of the split function:

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";
}

If you're into one-liners, the following would achieve the same:

$ perl -F/:\s*/ -ane '$attrib{$F[0]} = $F[1]; } END { print $_,"\t",$attrib{$_},"\n" foreach keys %attrib;" fileName
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号