preg_match('/\.(?!pdf)$/', $file)
I want to match all files except pdf files
path/file.jpg # match
path/file.png # match
path/file.pdf # not match
preg_match('/\.(?!pdf)$/', $file)
I want to match all files except pdf files
path/file.jpg # match
path/file.png # match
path/file.pdf # not match
Instead of using regex, you can take the extension of your file and check if it's a pdf.
$ext = pathinfo($file, PATHINFO_EXTENSION);
if($ext != 'pdf'){
echo "I'm not a pdf";
}
If you prefer using regex
<?php
$file = array("path/file.jpg", "path/file.png", "path/file.pdf");
foreach ($file as &$value) {
preg_match('/^(.(?!.*\.pdf$))*$/', $value, $matches);
if(!empty($matches)){
echo " $value is not a pdf";
}
}
If you want to use a regex, this one will work:
^(?!.*\.pdf).*$
It simply uses a negative lookahead to assert that the filename doesn't end in .pdf
and then .*
to match everything in the filename.
In PHP:
$filenames = array('path/file.jpg','path/file.png','path/file.pdf');
foreach ($filenames as $filename) {
if (preg_match('/^(?!.*\.pdf).*$/', $filename)) echo "\"$filename\" is not a PDF file.\n";
}
Output:
"path/file.jpg" is not a PDF file.
"path/file.png" is not a PDF file.
Asserting that something is not present in a regex is often fiddly, because a regex works by looking through the input for things to match.
The approach you've used is a "zero-width negative look-ahead assertion" - it matches anywhere in the string that isn't followed by pdf
, but doesn't "use up" any input. So your regex doesn't work because the rest of it still needs to match, and that is /\.$/
, meaning ".
at end of string".
The simplest approach is to look for strings that do end .pdf
, e.g. if ( ! preg_match('/\.pdf$/', $file) ) { ... }
.