在PHP中使用正则表达式检查文件扩展名

18

我正在阅读单个目录中的所有文件,并希望过滤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个回答

38

我认为你的正则表达式有问题。首先在这里测试一下正则表达式:https://www.regexpal.com/

我认为这个正则表达式可能适合你:

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

请注意末尾的/i - 这是“不区分大小写”的标志,可以节省您输入所有排列的时间 :)

11

使用 glob() 代替如何?

$files = glob($dir . '*.{jpg,gif,png,jpeg}',GLOB_BRACE);

1
顺便提一下,请确保$dir以目录分隔符结尾。 - Powerlord
有没有办法使用这个函数,仅返回文件名而不包括完整路径? - zeros-and-ones

3

你不想使用 scandirpathinfo 有什么原因吗?

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%正确。


这个答案应该在顶部。正则表达式通常过于复杂。我喜欢它们,但在可能的情况下必须坚持KISS原则。 - Bite code

2

这对我来说很有效

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

最好的。

1

你应该在正则表达式周围加上斜杠。 -> "/(...)/"


0

以下是从目标目录编译文件类型(演示用conf)的两种不同方法。我不确定哪种在性能方面更好。

    $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

有几种方法可以做到这一点。

你尝试过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';

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接