Re: Case insensitive file open in Perl

Jonathan Hall <[email protected]>
Newsgroups gmane.org.user-groups.aclug.discussion
Message-ID <[email protected]>
You could use /i, or you could just convert everything to upper or 
lowercase before doing your comparison--which will probably be more 
efficient.

my $lcfilename = lc( $filename_from_user );
opendir my $DIR,"/download/directory/somewhere";
while (my $filename = readdir $DIR ) {
    next unless $lcfilename eq lc( $filename );
    open my $FILE, "/download/directory/somewhere/$filename";
    while (<$FILE>) {
        # Do stuff
    }
    close $FILE;
    last;  # If you only want to operate on the first file that matches
}
closedir $DIR;

Note:  As a matter of style, I prefer to use a my $variable, versus a 
bareword for file handles and directory handles.  I feel it makes for 
cleaner code.  If I forget to explicitly close() my file handle, it 
doesn't stick around indefinitely--it will automatically be garbage 
collected and closed as soon as the my-scoped variable goes out of 
scope.  I've fixed bugs like this in other people's code before.  You 
should still explicitly close your files... but if you forget, you won't 
have surprises waiting for you later :)

If you choose to use /i instead of "eq lc()", be sure to use ^ and $ to 
anchor your argument.  In your example, you had:

	if ($_ =~ /myfilename.ext/i) {


This will correctly match "MyFileName.ext", "MYFILENAME.ext", and 
"myfilname.ext", but it will also match "ThisIsNotMyFilename.ext" and 
"MyFileName.extrastuff.that.you.dont.want.txt".  Another reason why I 
prefer lc() and eq... But you could compensate by wrapping your filename 
with ^ and $, as in:

	if ($_ =~ /^myfilename.ext$/i) {

That makes sure it contains the desired text, and that it's anchored at the beginning and end of the string.  Anchoring this way probably also gets rid of most of the overhead of using regex here, to the point that it would be almost as efficient as using lc() and eq.  To find out for sure, write a simple test that loops 1,000,000 times or so, and run it both ways and time it :)

--
Jonathan


Nate Bargmann wrote:
> Maybe I'm just braindead tonight (likely as it seems as though I've not
> adjusted to the time change yet).
>
> I'm working on a program that will load a user supplied file.  Since
> the file will be downloaded from the Web, it's possible that it will be
> all upper case, all lower, or a mixture.  Nice, huh?
>
> I'm trying to recall how one goes about doing a case insensitive search
> for the filename.  I know that I can use the //i matching operator. 
> Would a foreach loop and passing each glob by the /filename.ext/i match
> be the way to go?
>
> Thanks!
>
> - Nate >>
>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.