Проверка расширений файлов в PHP с помощью регулярных выражений - PullRequest
16 голосов
/ 26 ноября 2008

Я читаю все файлы в одном каталоге и хочу отфильтровать по 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;
  }

И это всегда ничего не возвращает. Что-то должно быть не так с моим кодом регулярных выражений.

Ответы [ 7 ]

33 голосов
/ 26 ноября 2008

Я думаю, что-то не так с вашим регулярным выражением. Попробуйте сначала проверить регулярные выражения: https://www.regexpal.com/

Я думаю, что этот может работать для вас:

/^.*\.(jpg|jpeg|png|gif)$/i

Обратите внимание на / i в конце - это флаг "без учета регистра", избавляющий вас от необходимости печатать все перестановки:)

11 голосов
/ 26 ноября 2008

Как насчет использования glob () вместо?

$files = glob($dir . '*.{jpg,gif,png,jpeg}',GLOB_BRACE);
2 голосов
/ 26 ноября 2008

Есть ли причина, по которой вы не хотите использовать 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% правильным.

1 голос
/ 19 февраля 2016

Это работает для меня

$string = "your-file-name.jpg";
preg_match("/\b(\.jpg|\.JPG|\.png|\.PNG|\.gif|\.GIF)\b/", $string, $output_array);

Best.

1 голос
/ 26 ноября 2008

Вы должны поставить косые черты вокруг вашего регулярного выражения. -> "/(...)/"

0 голосов
/ 29 сентября 2016

Вот два разных способа скомпилировать массив файлов по типу (conf для 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);
0 голосов
/ 26 ноября 2008

Есть несколько способов сделать это.

Вы пробовали 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';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...