Jon J
Jon J

Reputation: 445

Perl Array of regular expressions -- matching elements of an array

I am trying to match and remove elements from an array called @array. The elements to be removed must match the patterns stored inside an array called @del_pattern

my @del_pattern = ('input', 'output', 'wire', 'reg', '\b;\b', '\b,\b');

my @array = (['input', 'port_a', ','],
             ['output', '[31:0]', 'port_b,', 'port_c', ',']); 

To remove the patterns contained in @del_pattern from @array, I loop through all the elements in @del_pattern and exclude them using grep.

## delete the patterns found in @del_pattern array
foreach $item (@del_pattern) {
    foreach $i (@array) {
        @$i = grep(!/$item/, @$i);
    }
}

However, I have been unable to remove ',' from @array. If I use ',' instead of '\b,\b' in @del_pattern, element port_b, gets removed from the @array as well, which is not an intended outcome. I am only interested in removing elements that contain only ','.

Upvotes: 1

Views: 2789

Answers (3)

ikegami
ikegami

Reputation: 385506

You want

^,\z

An explanation of what \b doesn't match at all follows.


\b

defines the boundary of a "word". It is equivalent to

(?<=\w)(?!\w) | (?<!\w)(?=\w)

so

\b,\b

is equivalent to

(?: (?<=\w)(?!\w) | (?<!\w)(?=\w) ) , (?: (?<=\w)(?!\w) | (?<!\w)(?=\w) )

Since comma is a non-word character, that simplifies to

(?<=\w),(?=\w)

So

'a,b' =~ /\b,\b/      # Match
','   =~ /\b,\b/      # No match

Upvotes: 1

FrankTheTank_12345
FrankTheTank_12345

Reputation: 580

This works, but not very nice from the code. This code snippet also removes the ','

 my $elm = [];

sub extract {
   my $elm = shift;

   foreach my $del (@del_pattern) {
      $elm =~ s/$del//g;
      if ( $elm ) {
         return $elm;
      }
   }
}


foreach my $item (@array) {
    foreach my $i (@$item) {
        my $extract = extract($i);
        if ($extract) {
           push(@$elm, $extract);
        }
    }
}

print Dumper($elm);

Why your @array has array? Why not one big array?

Upvotes: 0

Mohit
Mohit

Reputation: 608

You are using the wrong regular expression. I updated the code and tried it and its working fine. PFB the update code:

my @del_pattern = ('input', 'output', 'wire', 'reg', '\b;\b', '^,$');

my @array = (['input', 'port_a', ','],
             ['output', '[31:0]', 'port_b,', 'port_c', ',']); 
## delete the patterns found in @del_pattern array
foreach my $item (@del_pattern) {
    foreach my $i (@array) {
        @$i = grep(!/$item/, @$i);
    }
}

The only change made is in the Regex '\b,\b' to '^,$'. I don't have much info on \b but the regex I am suggesting is doing what you intend.

Upvotes: 3

Related Questions