walker - php regexiterator count




How to use RegexIterator in PHP (2)

I have yet to find a good example of how to use the php RegexIterator to recursively traverse a directory.

The end result would be I want to specify a directory and find all files in it with some given extensions. Say for example only html/php extensions. Furthermore, I want to filter out folders such of the type .Trash-0, .Trash-500 etc.

<?php 
$Directory = new RecursiveDirectoryIterator("/var/www/dev/");
$It = new RecursiveIteratorIterator($Directory);
$Regex = new RegexIterator($It,'/^.+\.php$/i',RecursiveRegexIterator::GET_MATCH);

foreach($Regex as $v){
    echo $value."<br/>";
}
?>

Is what I have so far but result in : Fatal error: Uncaught exception 'UnexpectedValueException' with message 'RecursiveDirectoryIterator::__construct(/media/hdmovies1/.Trash-0)

Any suggestions?


An improvement to salathe, would be to forget about the custom abstract class. Just use good OOP in PHP and directly extend RecursiveRegexIterator instead:

Here is the File filter

class FilenameFilter 
extends RecursiveRegexIterator 
{
    // Filter files against the regex
    public function accept() 
    {
        return ! $this->isFile() || parent::accept();
    }
}

And the Directory filter

class DirnameFilter 
extends RecursiveRegexIterator 
{
    // Filter directories against the regex
    public function accept() {
        return ! $this->isDir() || parent::accept();
    }
}

The docs are indeed not much helpful. There's a problem using a regex for 'does not match' here, but we'll illustrate a working example first:

<?php 
//we want to iterate a directory
$Directory = new RecursiveDirectoryIterator("/var/dir");

//we need to iterate recursively
$It        = new RecursiveIteratorIterator($Directory);

//We want to stop decending in directories named '.Trash[0-9]+'
$Regex1    = new RecursiveRegexIterator($It,'%([^0-9]|^)(?<!/.Trash-)[0-9]*$%');

//But, still continue on doing it **recursively**
$It2       = new RecursiveIteratorIterator($Regex1); 

//Now, match files
$Regex2    = new RegexIterator($It2,'/\.php$/i');
foreach($Regex2 as $v){
  echo $v."\n";
}
?>

The problem is the doesn't match .Trash[0-9]{3} part: The only way I know how to negative match the directory, is match the end of the string $, and then then assert with a lookbehind (?<!/foo) 'if it is not preceded by '/foo'.

However, as .Trash[0-9]{1,3} is not fixed length, we cannot use it as a lookbehind assertion. Unfortunately, there is no 'invert match' for a RegexIterator. But perhaps there are more regex-savvy people then I knowing how to match 'any string not ending with .Trash[0-9]+


edit: got it '%([^0-9]|^)(?<!/.Trash-)[0-9]*$%' as a regex would do the trick.







spl