Carson Myers
Carson Myers

Reputation: 38564

How can I make sure one thing matches, and one doesn't, in a single regex?

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

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?

Upvotes: 1

Views: 112

Answers (3)

Geert
Geert

Reputation: 1824

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.

Upvotes: 1

Jose Gonzalez
Jose Gonzalez

Reputation:

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

Upvotes: 0

John Kugelman
John Kugelman

Reputation: 361937

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

Upvotes: 6

Related Questions