Comparez les prix des domaines et des services informatiques des vendeurs du monde entier

Comment utiliser RegexIterator dans PHP

Je dois toujours trouver un bon exemple de comment utiliser php RegexIterator Pour le catalogue récursif.

Le résultat final sera ce que je souhaite spécifier le répertoire et trouvera tous les fichiers avec certaines extensions spécifiées. Disons, par exemple, seulement des extensions html/php. De plus, je veux filtrer les dossiers de ce type. Museum-0, déchets-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/";
}
?>


C'est ce que j'ai jusqu'à présent, mais le résultat: erreur fatale: exception non précise 'UnexpectedValueException' Avec un message 'RecursiveDirectoryIterator::__construct//media/hdmovies1/.Trash-0/

Avez-vous des idées?
Invité:

Charles

Confirmation de:

Il existe différentes façons de faire quelque chose de similaire, je vous donnerai deux approches rapides: rapide et sale, et plus plus et moins sale /Bien qu'aujourd'hui soit vendredi, nous sommes donc autorisés à devenir fou/.

1. vite /Et sale

/

Cela inclut simplement écrire une expression régulière. /peut être divisé en plusieurs/, Pour l'utiliser pour filtrer la collection de fichiers par un rapide dans un plus rapide.

/Seules deux lignes commentées sont vraiment importantes pour le concept.

/


$directory = new RecursiveDirectoryIterator/__DIR__/;
$flattened = new RecursiveIteratorIterator/$directory/;

// Make sure the path does not contain "/.Trash*" folders and ends eith a .php or .html file
$files = new RegexIterator/$flattened, '#^/?:[A-Z]:/?/?://?!\.Trash/[^/]+/+/[^/]+\./?:php|html/$#Di'/;

foreach/$files as $file/ {
echo $file . PHP_EOL;
}


Cette approche présente un certain nombre de problèmes, bien qu'il soit rapidement mis en œuvre, n'étant qu'une seule fois /même si regex peut être difficile à déchiffrer/.

2. Moins vite /et moins de dumping

/

Approche plus réutilisable - Créez une paire de filtres pour commander /Utilisant regex Ou qu'est-ce que tu aimes!/ Réduire la liste des éléments disponibles dans l'initiale
RecursiveDirectoryIterator

Avant ceux dont vous avez besoin. Ci-dessous n'est qu'un exemple, écrit rapidement pour vous, expansion
RecursiveRegexIterator

.

Nous commençons par une classe de base, dont la tâche principale est de tenir regex, Avec lequel nous voulons filtrer, tout le reste est reporté à
RecursiveRegexIterator

. Notez que la classe
abstract

, Comme en fait, il n'est pas

Fait

Rien d'utile: le filtrage réel doit être effectué par deux classes qui l'élargiront. De plus, il peut être appelé
FilesystemRegexFilter

, Mais rien ne le force /À ce niveau/ Cours de système de fichiers filtres /Je choisirais le meilleur nom si ce n'était pas si endormi/.


abstract class FilesystemRegexFilter extends RecursiveRegexIterator {
protected $regex;
public function __construct/RecursiveIterator $it, $regex/ {
$this->regex = $regex;
parent::__construct/$it, $regex/;
}
}


Ces deux classes sont des filtres très simples fonctionnant en fonction du nom du fichier et du nom du répertoire.


class FilenameFilter extends FilesystemRegexFilter {
// Filter files against the regex
public function accept// {
return / ! $this->isFile// || preg_match/$this->regex, $this->getFilename////;
}
}

class DirnameFilter extends FilesystemRegexFilter {
// Filter directories against the regex
public function accept// {
return / ! $this->isDir// || preg_match/$this->regex, $this->getFilename////;
}
}


Pour les appliquer dans la pratique, l'itération suivante répète récursivement le contenu du répertoire dans lequel le script est situé /N'hésitez pas à le modifier!/, Et filtrage des dossiers
.Trash

/S'assurer que les noms de dossiers

correspondre

avec spécialement créé regex/, et reçoit également uniquement des fichiers PHP et HTML.


$directory = new RecursiveDirectoryIterator/__DIR__/;
// Filter out ".Trash*" folders
$filter = new DirnameFilter/$directory, '/^/?!\.Trash//'/;
// Filter PHP/HTML files
$filter = new FilenameFilter/$filter, '/\./?:php|html/$/'/;

foreach/new RecursiveIteratorIterator/$filter/ as $file/ {
echo $file . PHP_EOL;
}


Il convient de noter que, puisque nos filtres sont récursifs, nous pouvons jouer avec la manière de les traverser. Par exemple, nous pourrions facilement nous limiter à numériser uniquement à 2 Niveaux de profondeur /Y compris le dossier initial/, Après:


$files = new RecursiveIteratorIterator/$filter/;
$files->setMaxDepth/1/; // Two levels, the parameter is zero-based.
foreach/$files as $file/ {
echo $file . PHP_EOL;
}


De plus, il est très facile d'ajouter encore plus de filtres /Après avoir créé plus de nos classes de filtrage avec diverses expressions régulières; ou créer de nouvelles classes de filtrage/ Pour plus de besoins de filtrage spécialisés /Par exemple, la taille du fichier, la longueur du chemin complet, etc./.

P.S. Hmm, cette réponse est un peu malicieuse; J'ai essayé de le rendre aussi bref que possible. /Même en supprimant d'énormes rayures de super-lepture/. Je m'excuse si le résultat final laisse la réponse à incohérente.

Eugene

Confirmation de:

Les documents ne sont vraiment pas très utiles. Il y a un problème d'utilisation regex pour "ne correspond pas", Mais d'abord, nous illustrerons l'exemple de travail:


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";
}
?


Le problème est cette partie doesn't match
.Trash[0-9]{3}

: la seule façon de savoir comment se conformer négativement au catalogue - c'est

conformité

Fin de la chaîne
$

, puis approuver avec lookbehind
/?/foo/

', Si elle ne précède pas '/foo'.

Cependant, depuis
.Trash[0-9]{1,3}

Non fixé longtemps, nous ne pouvons pas l'utiliser comme une déclaration lookbehind. Malheureusement non 'invert match' pour RegexIterator. Mais peut-être, il y a peut-être plus de personnes évoquées par les regex que je sais comment comparer ' Toute chaîne qui ne se termine pas avec
.Trash[0-9]+


Éditer

: j'ai compris
'%/[^0-9]|^//?<!/.Trash-/[0-9]*$%'

comme regex fera un tour.
</div
<div class="answer_text">
Amélioration de salathe Il serait oublier de la classe d'abstraction utilisateur.
Il suffit d'utiliser de bien OOP dans PHP et directement au lieu d'étendre RecursiveRegexIterator :

Voici un filtre de fichiers


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


Et catalogues de filtrage


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


</div>

Gilles

Confirmation de:

Amélioration de salathe Il serait oublier de la classe d'abstraction utilisateur.
Il suffit d'utiliser de bien OOP dans PHP et directement au lieu d'étendre RecursiveRegexIterator :

Voici un filtre de fichiers


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


Et catalogues de filtrage


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

Pour répondre aux questions, connectez-vous ou registre