How to exclude certain elements in an array with pattern matching

Problem: You’re writing a Perl script, you have an array of elements, and you need to process every element in the array, except the elements that match a given regular expression (pattern).

Solution: You can solve this problem using a combination of the Perl regular expression pattern matching, along with the next operator.

A simple example

The source code below shows a simple example where I want to print every filename in an array whose name (the complete path to the file, really) does not include the simple string bar:

@files = qw(/foo/bar/file.pdf /foo/baz/file2.jpg);

foreach $file (@files) {
    # exclude any files whose full name contains the string 'bar'
    next if $file =~ /bar/;

    # print all other files
    print "$file\n";
}

As you can see, this is a simple foreach example where I loop over the @files array, and run a simple pattern match against each element in the array. Within the loop I use the next operator to bypass any filenames that match my pattern.

When you run this Perl program the string with bar in it is skipped, and the output looks like this:

/foo/baz/file2.jpg

A more complicated example

My real-world example looks much more like the following code. In this code I'm saying that I do not want to operate on any file in my array that contains the pattern /usr/bin/.

In this example I've mocked up my array (@files) with just two strings, but in my actual code this array was fed to my program as input.

(If it helps to know it, my code was actually running against a Linux filesystem. I was getting all events from the Linux filesystem, and what I had to do was weed out all the events I didn't care about, so I could then operate on all the events I did care about. In this case it was much easier to weed out certain sub-directory patterns, because these patterns were easy to describe, and I was really interested in about 95% of the overall events.)

@files = qw(/usr/bin/file.pdf /usr/baz/file2.jpg);

foreach $file (@files) {
    # exclude any files in the /usr/bin/ hierarchy
    next if $file =~ /\/usr\/bin\//;

    # print all other files
    print "$file\n";
}

Notes about this Perl code

Here are a few quick notes about this code:

  • This example shows how to match a pattern against a string.
  • It shows how to use the next operator to skip over elements in an array in a for or foreach loop.
  • If you haven't seen it before, it shows how to use the characters \/ in a pattern to specify that you really are trying to match a / character in a string. (You essentially have to escape the / with the \ character within a pattern.)