Проверка расширений файлов в PHP с помощью регулярных выражений
Я читаю все файлы в одном каталоге, и я хочу фильтровать JPG, JPEG, GIF и PNG.
И капитальные, и маленькие буквы. Это единственные файлы, которые нужно принять.
В настоящее время я использую это:
$testPics = takeFiles($picsDir, "([^\s]+(?=\.(jpg|JPG|jpeg|JPEG|png|PNG|gif|GIF))\.\2)");
и функция takeFiles выглядит так:
function takerFiles($dir, $rex="") {
$dir .= "/";
$files = array();
$dp = opendir($dir);
while ($file = readdir($dp)) {
if ($file == '.') continue;
if ($file == '..') continue;
if (is_dir($file)) continue;
if ($rex!="" && !preg_match($rex, $file)) continue;
$files[] = $file;
}
closedir($dp);
return $files;
}
И он всегда ничего не возвращает. Поэтому с моим кодом регулярного выражения что-то должно быть не так.
Ответы
Ответ 1
Я думаю, что-то не так с вашим регулярным выражением. Попробуйте сначала протестировать регулярные выражения: https://www.regexpal.com/
Я думаю, что это может работать для вас:
/^.*\.(jpg|jpeg|png|gif)$/i
Обратите внимание на /i в конце - это флаг "без учета регистра", избавляющий вас от необходимости печатать все перестановки :)
Ответ 2
Как использовать glob() вместо?
$files = glob($dir . '*.{jpg,gif,png,jpeg}',GLOB_BRACE);
Ответ 3
Есть ли причина, по которой вы не хотите использовать scandir
и pathinfo
?
public function scanForFiles($path, array $exts)
{
$files = scanDir($path);
$return = array();
foreach($files as $file)
{
if($file != '.' && $file != '..')
{
if(in_array(pathinfo($file, PATHINFO_EXTENSION), $exts))) {
$return[] = $file;
}
}
}
return $return;
}
Таким образом, вы также можете проверить, является ли файл каталогом и выполнить рекурсивный вызов для сканирования этого каталога. Я написал код в спешке, поэтому может быть не на 100% правильным.
Ответ 4
Вы должны поместить косые черты вокруг своего регулярного выражения. → "/(...)/"
Ответ 5
Это работает для меня
$string = "your-file-name.jpg";
preg_match("/\b(\.jpg|\.JPG|\.png|\.PNG|\.gif|\.GIF)\b/", $string, $output_array);
Бест.
Ответ 6
Есть несколько способов сделать это.
Вы пробовали glob()?:
$files = glob("{$picsDir}/*.{gif,jpeg,jpg,png}", GLOB_BRACE);
Вы считали pathinfo()?:
$info = pathinfo($file);
switch(strtolower($info['extension'])) {
case 'jpeg':
case 'jpg':
case 'gif':
case 'png':
$files[] = $file;
break;
}
Если вы настаиваете на использовании обычного выражения, нет необходимости сопоставлять полное имя файла, просто расширение. Используйте токен $
, чтобы он соответствовал концу строки, и используйте флаг i
для обозначения нечувствительности к регистру. Кроме того, не забудьте использовать разделитель в вашем выражении, в моем случае "%":
$rex = '%\.(gif|jpe?g|png)$%i';
Ответ 7
Вот два разных способа скомпилировать массив файлов по типу (conf for demo) из целевого каталога. Я не уверен, какая из них лучше по производительности.
$path = '/etc/apache2/';
$conf_files = [];
// Remove . and .. from the returned array from scandir
$files = array_diff(scandir($path), array('.', '..'));
foreach($files as $file) {
if(in_array(pathinfo($file, PATHINFO_EXTENSION), ['conf'])) {
$conf_files[] = $file;
}
}
return $conf_files;
Это вернет полный путь к файлу, а не только имя файла
return $files = glob($path . '*.{conf}',GLOB_BRACE);