PHP递归正则表达式过滤器迭代器迭代器

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (97)

我只是试图循环遍历目录中的所有文件,递归地过滤到只匹配模式的文件。

原来,RegexIterator为您提供了正则表达式匹配对象,但我想要该SplInfo对象。

所以这是我得到的:

class RegexFilterIterator extends RecursiveFilterIterator {

    private $pattern;

    public function __construct(RecursiveIterator $iterator, $pattern) {
        parent::__construct($iterator);
        $this->pattern = $pattern;
    }


    public function accept() {
        return preg_match($this->pattern, $this->current()->getFilename()) > 0;
    }
}

$dir = new RecursiveDirectoryIterator($argv[1]);
$regex = new RegexFilterIterator($dir, '/\.php5?\z/i');
$it = new RecursiveIteratorIterator($regex);



foreach($it as $foo) {
   echo $foo->getPathname().PHP_EOL;
}

但是这似乎不是递归的。

稍微修改一下:

public function accept() {
    return $this->current()->isDir() || preg_match($this->pattern, $this->current()->getFilename()) > 0;
}

现在它崩溃了:

PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function RegexFilterIterator::__construct(), 1 passed and exactly 2 expected in bleep

这对我没有任何意义。为什么要试图RegexFilterIterator自行构建更多的实例,它是如何搞砸的?

我会把RegexFilterIterator 后面RecursiveIteratorIterator,但它然后说:

PHP Fatal error: Uncaught TypeError: Argument 1 passed to RegexFilterIterator::__construct() must implement interface RecursiveIterator, instance of RecursiveIteratorIterator given

如何缓存目录中的所有文件,并使用简单的正则表达式对它们进行过滤,并让我返回一个生成SplInfo对象的生成器/迭代器?

提问于
用户回答回答于
$directory = new \RecursiveDirectoryIterator($argv[1], \FilesystemIterator::SKIP_DOTS);
$filter = new \RecursiveCallbackFilterIterator($directory, function ($current, $key, $iterator) {
    return $current->isDir() || preg_match('/\.php5?\z/',$current->getPathname()) > 0;
});
$iterator = new \RecursiveIteratorIterator($filter);

foreach($iterator as $file) {
   echo $file->getPathname().PHP_EOL;
}
用户回答回答于
function readDirRecursive($dir, $pattern=null) {
    $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS));
    foreach($iterator as $it) {
        if($it->isFile() && ($pattern===null || preg_match($pattern, $it->getPathname()))) {
            yield $it;
        }
    }
}


$iterator = readDirRecursive($argv[1],'/\.php5?\z/');

foreach($iterator as $file) {
   echo $file->getPathname().PHP_EOL;
}

扫码关注云+社区

领取腾讯云代金券