Forum |  HardWare.fr | News | Articles | PC | Prix | S'identifier | S'inscrire | Shop Recherche
1900 connectés 

  FORUM HardWare.fr
  Programmation
  PHP

  Preg_match match mais ne capture pas

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Preg_match match mais ne capture pas

n°2350426
MaybeEijOr​Not
but someone at least
Posté le 01-04-2020 à 17:41:41  profilanswer
 

Bonjour,
 
Je liste des images dans un dossier, cela fonctionne très bien sauf pour une image en .png contrairement à toutes les autres qui sont en .jpg.
 
Donc je scanne tous les fichiers, puis à partir de leur nom j'applique une expression régulière qui élimine tout ce qui n'a pas la bonne extension, ensuite je récupère le nom de l'image sans son extension :
 

Code :
  1. function constr_ext($value) { //ajout du point devant le nom de l'extension
  2. return '\.' . $value;
  3. }
  4. $extensions = ['jpg', 'jpeg', 'png', 'gif']; //extensions recherchées
  5. $pattern = '/^(.+)' . implode('|', array_map('constr_ext', $extensions)) . '$/'; //expression régulière prenant en compte toutes les extensions souhaitées
  6. $files = scandir($dir1); //liste les fichiers dans le dossier
  7. foreach($files as $key => $value) {
  8. $test = preg_match($pattern, $value, $matches); //vérifie si le nom du fichier (avec extension) respecte l'expression régulière (nom de fichier se terminant par une des extensions listées)
  9. if($key == 275) { //test spécifique au fichier problématique
  10.  echo $matches[0];
  11. }
  12. if($test != 1) { //si ne respecte pas l'expression régulière on désindexe le fichier
  13.  unset($files[$key]);
  14. } else { //sinon on récupère son nom sans l'extension
  15.  $files[$key] = $matches[1];
  16. }
  17. }


 
J'ai inséré un test pour le fichier en question, $matches[0] me renvoie bien ".png" mais $matches[1] me renvoie NULL et $value vaut "256426.png".
 
Je ne capte pas, il détecte bien que dans le nom du fichier il y a l'extension mais ne veut pas capturer.
Le $pattern littéral obtenu est :

Code :
  1. /^(.+)\.jpg|\.jpeg|\.png|\.gif$/


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
mood
Publicité
Posté le 01-04-2020 à 17:41:41  profilanswer
 

n°2350428
MaybeEijOr​Not
but someone at least
Posté le 01-04-2020 à 17:43:52  profilanswer
 

Désolé, c'est déjà réglé, j'y ai vu plus clair en écrivant mon message, faut utiliser le pattern :

 
Code :
  1. /^(.+)(?:\.jpg|\.jpeg|\.png|\.gif)$/


Message édité par MaybeEijOrNot le 01-04-2020 à 17:58:17

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
n°2350621
Surfoo
Ça va ? ok.
Posté le 02-04-2020 à 22:06:30  profilanswer
 

Désolé mais ton code me semble bien compliqué :/
 
Avec le bout de code suivant, ça retourne tous les fichiers avec tes extensions voulues :


$files = preg_grep('/\.(jpeg|jpg|png|gif)$/', scandir($dir1));
 
$filesWithoutExtension = array_map(function($file) {
    return basename($file, '.' . pathinfo($file, PATHINFO_EXTENSION));
}, $files);
 
var_dump($filesWithoutExtension);


 
C'est mieux pour toi ?


Message édité par Surfoo le 02-04-2020 à 22:07:08
n°2350628
MaybeEijOr​Not
but someone at least
Posté le 03-04-2020 à 00:19:07  profilanswer
 

Euh je ne vois pas ce qu'il a de compliqué, il liste les fichiers d'un dossier puis élimine à l'aide d'une expression régulière ceux qui ne répondent pas au critère des extensions recherchées. C'est juste une boucle avec if dedans.

 

L'avantage de mon code, ce qui quitte à utiliser une expression régulière, autant aller jusqu'au bout en utilisant son résultat.

 

Ce qui peut paraître complexe c'est la création du regex mais c'est parce que je veux partir d'un tableau.

 

Au final, ton code est plus "court" (tu écris moins de lignes mais ne fait pas moins d'opérations) mais est probablement moins performant (tu boucles deux fois sur ta liste de fichiers dont un array_map qui applique deux fonctions) et tu ne gagnes pas vraiment en lisibilité.

Message cité 1 fois
Message édité par MaybeEijOrNot le 03-04-2020 à 00:20:13

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
n°2350650
B4X
kebab-case
Posté le 03-04-2020 à 11:33:42  profilanswer
 

MaybeEijOrNot a écrit :

Euh je ne vois pas ce qu'il a de compliqué, il liste les fichiers d'un dossier puis élimine à l'aide d'une expression régulière ceux qui ne répondent pas au critère des extensions recherchées. C'est juste une boucle avec if dedans.
 
L'avantage de mon code, ce qui quitte à utiliser une expression régulière, autant aller jusqu'au bout en utilisant son résultat.
 
Ce qui peut paraître complexe c'est la création du regex mais c'est parce que je veux partir d'un tableau.
 
Au final, ton code est plus "court" (tu écris moins de lignes mais ne fait pas moins d'opérations) mais est probablement moins performant (tu boucles deux fois sur ta liste de fichiers dont un array_map qui applique deux fonctions) et tu ne gagnes pas vraiment en lisibilité.


 
Le code proposé par Surfoo est infiniment plus élégant et lisible que ta bidouille [:b4x]  
 
Il n'est rien de plus lent que ton ```preg_match()``` dans ton ```foreach()```. Tu multiplie le nombre d'itérations par le nombre de regex steps, je te laisse faire le calcul [:cetrio:4]  
 
Le pire étant ta custom fonction ```constr_ext()```, elle met très mal à l'aise soyons honnête [:b4x:4]


---------------
In vanitas veritas.
n°2350687
MaybeEijOr​Not
but someone at least
Posté le 03-04-2020 à 15:24:45  profilanswer
 

B4X a écrit :

Il n'est rien de plus lent que ton ```preg_match()``` dans ton ```foreach()```. Tu multiplie le nombre d'itérations par le nombre de regex steps, je te laisse faire le calcul [:cetrio:4]


Il fait exactement la même chose :

Code :
  1. preg_grep('/\.(jpeg|jpg|png|gif)$/', scandir($dir1))


Ce n'est pas de la magie, ça fait juste répéter un preg_match sur chaque itération du tableau passé en paramètre. :pt1cable:  
 
Comme je le disais, j'utilise une boucle de taille n lorsque lui utilise deux boucles de taille n, le calcul est vite fait !
 
On est d'accord que le regex en dur est plus clair mais ne répond pas à la problématique (que j'ai partiellement exposé) qui fait que le regex n'est pas connu à l'avance.
 
 
EDIT : j'ai simplifié la construction du regex (plus de map) :

Code :
  1. $pattern = '/^.+(?:\.' . implode('|\.',$extensions) . ')$/';


Message édité par MaybeEijOrNot le 03-04-2020 à 15:29:29

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
n°2350754
B4X
kebab-case
Posté le 03-04-2020 à 22:57:57  profilanswer
 

il boucle exclusivement sur les fichiers qui l'intéresse (rendement = 100%), tu boucle autant de fois qu'il y a de fichiers dans ton répertoire [:cetrio:4]


---------------
In vanitas veritas.
n°2350756
MaybeEijOr​Not
but someone at least
Posté le 03-04-2020 à 23:13:41  profilanswer
 

Plus ou moins, en fait il fait une boucle de taille n puis une boucle plus courte (plus courte des fichiers éliminés). Là où encore une fois je ne fais qu'une boucle de taille n. [:transparency]  
Et même côté mémoire, il instancie un tableau de la taille du nombre de fichiers (comme moi avec scandir), puis instancie un second tableau avec le preg_grep, là où je reste avec un seul tableau.
Alors même si on n'est pas dans le besoin de l'extrême performance, je suis sur 500-1000 fichiers, c'est loin d'être critique mais pas non plus suffisamment anecdotique pour choisir une légère meilleure lisibilité ? [:cond]


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
n°2350757
MaybeEijOr​Not
but someone at least
Posté le 03-04-2020 à 23:34:31  profilanswer
 

Par contre je viens de me rendre compte qu'il y avait mésentente, il me retourne la liste des fichiers sans leur extension, moi je veux garder l'extension du fichier, je veux juste éliminer ceux qui n'ont pas l'extension voulue.
Du coup son code se simplifie à :

Code :
  1. $files = preg_grep($pattern, scandir($dir1));


 
Et là je dis oui ! Même si après quelques tests de performance, la différence avec mon code est minime, on est plus rapide de 0,05 - 0,1 ms maintenant. :)


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  PHP

  Preg_match match mais ne capture pas

 

Sujets relatifs
Capture de sous-chaîne matching expression reguliere[Résolu] Aide pour un preg_match_all récalcitrant
[Résolu PHP]aide pour passer de preg_replace à preg_replace_callback[C++] Lambda capture de pointeur
Macro capture d'écranfaire une capture d'acran
[MYSQL] Query sur une partie d'un terme avec MATCH AGAINST[C#] Capture d'écran en jeu
[PHP] Remplacer preg_replace par preg_replace_callback 
Plus de sujets relatifs à : Preg_match match mais ne capture pas


Copyright © 1997-2018 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR