1

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 ','.

5
  • Try using '^\,$' instead for removing the words having only , as the pattern you are using will remove all words having , anywhere in them. Commented May 17, 2017 at 5:32
  • So if you had input_a in @array should that get removed? In other words, do patterns need to match or to be equal? For the comma you are saying that it should be equal -- "that contain only ," (my emphasis). Commented May 17, 2017 at 6:24
  • If I had input_a in @array, it shouldn't get removed. The patterns need to match Commented May 17, 2017 at 7:21
  • OK -- but not the comma? With it, you remove an element only when it is exactly the comma? If that is the case, it makes most sense to make that regex /^,$/, so that matching it means that it is equal. Commented May 17, 2017 at 7:30
  • Also, you should make your regex with qr/.../ (not just single quotes). Commented May 17, 2017 at 7:32

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

^,$ will remove both , and ,␊. ^,\z is the correct solution.
1

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

Comments

0

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?

1 Comment

It is a nested array. The original array contains a list of lines, where a single line is an element. A line is then split with space as delimiter, which forms array within an array. I structured it such that it would be easier for me to trace if there is a bug

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.