Sined Strategy
Sined Strategy

Reputation: 39

Can't combine two regex statements to work at once

I have a simple perl code that displays the names of the files in a given directory

opendir my $dir, "./images/sampleImages" or die "Cannot open directory: $!";
my @Images = grep {!/^\./} readdir $dir;
closedir $dir;

I have added a regex statement to remove all single and double dots, since readdir adds them as special characters and this is working perfectly fine. However I want only the files with the extensions of .jpg/.jpeg/.png/.gif to be read. I have found a regex that does that, which is :

(/\.(gif|jpg|jpeg|png)$/i)

But I can't seem to make them work together. I have tried everything I could find on the subject here, combining the statements in different ways but either they give errors, or flat out do not work the way it should. Any help would be greatly appreciated, thanks in advance!

Upvotes: 0

Views: 81

Answers (3)

Polar Bear
Polar Bear

Reputation: 6798

Following code filters in only images, no need to look at . and .. at all

use strict;
use warnings;

use feature 'say';

my $dirname = './images/sampleImages';

opendir my $dir, $dirname 
    or die "Cannot open directory: $dirname";

my @Images = grep { /\.(gif|jpg|jpeg|png)$/i } readdir $dir;

closedir $dir;

map{ say } @Images;

Upvotes: 0

brian d foy
brian d foy

Reputation: 132773

You can use multiple match operators:

 my @dirs =
     grep { /\.(?:gif|jpe?g|png)\z/i && ! /\A\./ }
     readdir $dir;

I typically make one grep per idea so I can disable them individually:

 my @dirs =
     grep { /\.(?:gif|jpe?g|png)\z/i }
     grep { ! /\A\./ }
     readdir $dir;

And often I add in a map to make the full path since readdir doesn't do that for you (and usually I do it wrong first then come back to do this):

 my @dirs =
     map  { catfile( $dir, $_ ) }
     grep { /\.(?:gif|jpe?g|png)\z/ }
     grep { ! /\A\./ }
     readdir $dir;

And, readdir doesn't "add" . and ... Those are the virtual directories that mean the current directory and the parent directory. If those are the only things that you want to remove, then you can improve that part to match only those rather than all hidden files:

 my @dirs =
     map  { catfile( $dir, $_ ) }
     grep { /\.(?:gif|jpe?g|png)\z/ }
     grep { ! /\A\.\.?\z/ }
     readdir $dir;

Again, even though I know that and written that a million times, I still only add it once I see . and .. in the output. Some things never change.

Upvotes: 3

pmqs
pmqs

Reputation: 3705

Does this work?

my @Images = grep { !/^\./ && /\.(gif|jpg|jpeg|png)$/i } readdir $dir;

Upvotes: 5

Related Questions