【问题标题】:Checking for file-extensions in PHP with Regular expressions使用正则表达式检查 PHP 中的文件扩展名
【发布时间】:2008-11-26 15:43:39
【问题描述】:

我正在读取单个目录中的所有文件,我想过滤 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;
  }

而且它总是什么也不返回。所以我的正则表达式代码一定有问题。

【问题讨论】:

    标签: php regex


    【解决方案1】:

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

    我认为这个可能对你有用:

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

    注意末尾的 /i - 这是“不区分大小写”标志,省去您输入所有排列的麻烦 :)

    【讨论】:

      【解决方案2】:

      您有什么理由不想使用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。
      【解决方案3】:

      这对我有用

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

      最好的。

      【讨论】:

        【解决方案4】:

        改用glob() 怎么样?

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

        【讨论】:

        • 附带说明,确保 $dir 以目录分隔符结尾。
        • 有没有办法使用这个函数并且只返回没有完整路径的文件名?
        【解决方案5】:

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

        【讨论】:

          【解决方案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)。我不确定哪个性能更好。

                $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);
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2017-12-17
              • 2010-09-19
              • 1970-01-01
              • 2013-03-18
              • 1970-01-01
              • 2010-12-21
              • 2014-05-02
              相关资源
              最近更新 更多