tags:

views:

74

answers:

3

This is simple, but I am taking an entire directory listing (in PHP with dir()), and making sure it both:

  • isn't "." or "..", and
  • ends in a file extension .jpg, .jpeg, .gif, or .png.

Right now I have

function isValidFile($filename) {
    $dirDotExpr = "/^\.{1,2}$/"; //matches against "." and ".."
    $extExpr = "/\.(jpg|jpeg|gif|png)$/i"; //checks file extension

    return (1
        && ! preg_match($dirDotExpr, $filename)
        && preg_match($extExpr, $filename)
    )
}

but it'd be nice to do it all in one regular expression. However, I don't know how to make sure one thing matches, and one thing doesn't--how can I accomplish this?

+6  A: 

You may be overthinking it. If you're verifying that $filename ends in .jpg, .jpeg, .gif, or .png, it clearly can't be "." or "..".

John Kugelman
you're right, thank you. I suppose it's because I originally just wanted to get rid of . and .., but then later thought I should make sure the files are of the right type too since I won't be the one maintaining the directory.
Carson Myers
A: 

If you do not want to allow periods in your file name (except for the delimiter of the name and extension): ^[^\x2E]+\x2E(jpg|jpeg|gif|png)$

If you do allow for periods (multi-part name): ^([^\x2E]+\x2E)+(jpg|jpeg|gif|png)$

Convert to PHP as required...

+1  A: 
function isValidFile($filename)
{
    return (bool) preg_match('/\.(?:jpe?g|gif|png)$/iD', (string) $filename);
}

Note that I made the parentheses non-capturing, for a minor speed increase. Also merged jpg and jpeg into jpe?g. Also, I added the D modifier. If you don't, $ will allow final newlines; a filename like "hello.jpg\n" would be considered valid. Be very aware of that.

Geert