Polar_Misha
Polar_Misha

Reputation: 13

Perl: Using grep to delete element of array that match a pattern and do not match another

I have two arrays which contain the following elements:

my @type = ("man", "boy"); 
my @array = (
          "=stat_man", 
          "=stat_boy" 
          "=ref_g_man",  
          "=g_man", 
          "=g_boy", 
          "=happy_man" ,
          "an element", 
          "another element", 
          "=ref_g_boy"
);

As an option, I want to delete only the lines in @array which contain the string 'stat', in the other case, I want it to delete the elements which do not contain the string 'stat', but contain an element of @type. So I wrote:

foreach my $type (@type) {
    if(condition) {
        @array = grep {! /stat_$type/}@array;     #works. Deletes elements with 'stat'
    }
    else {
        @array = grep {! /(?!stat)_$type/}@array; #sort of...works
    }
}

Ok, now here's where I get stuck. In the else, all elements that contain $type and do not contain 'stat' are deleted. Which is ok. But what I want is for the second grep to delete only the elements which contain $type, do not contain 'stat' and not delete the elements which have the prefix made up of more that 1 word.

For example, I want

"=g_man" , "=g_boy" and "=happy_man" deleted, but not "=ref_g_man" and "=ref_g_boy".  

If I add anything in front of the (?!stat) in the second grep, it doesn't work.

Basically, I'm at loss as to how to add the third condition to the grep.

Upvotes: 0

Views: 3310

Answers (1)

Schwern
Schwern

Reputation: 165606

You're trying to parse and filter at the same time, and that gets messy. It would be better to do them separately. I'll leave the parsing part up to you, you know the data better. You might come up with something like this.

my @stuff = (
    { type => "man", stat => 1 },
    { type => "boy", stat => 1 },
    { type => "man", g    => 1, ref => 1 },
    ...
);

Then the filtering becomes easier.

for my $type (@types) {
    @stuff = grep { $_->{type} eq $type } @stuff;
}

I think you should be able to go from here.

Upvotes: 2

Related Questions