Précédent   Forum du club des développeurs et IT Pro > PHP > Langage > Regex
Regex Forum d'entraide sur les expressions rationnelles PHP. Avant de poster -> FAQ regex, Cours de regex et Sources de regex
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 28/09/2012, 10h44   #1
jaudouy
Futur Membre du Club
 
Inscription : novembre 2005
Messages : 26
Détails du profil
Informations forums :
Inscription : novembre 2005
Messages : 26
Points : 17
Points : 17
Par défaut Extraire des parties du nom d'un fichier

Bonjour,

Je demande de l'aide aux cadors des expressions régulières car j'ai pas mal cherché une réponse avant de venir demander de l'aide ici mais je cherche à faire quelque chose d'un peu tricky (à mes yeux) avec une expression régulière mais mon résultat n'est que très partiel... et cela ne me conviens pas vraiment ;-)

J'ai un fichier avec un nom dont je veux extraire plusieurs groupes exemple:
WindowsServer2003-KB2722913-x86-ENU.exe

A l'aide de l'expression régulière suivante:
Code :
^.*(KB[0-9]+)[-_]?(V[0-9]+)?.*$
J'en extrait les groupes suivants :
Citation:
$2$1
Et donc j'obtiens le résultat suivant:
Citation:
KB2722913
Note: vous remarquerez que je récupère aussi les versions du KB (_v2, -v2, etc)

Bien, cela fonctionne très bien mais ce n'est pas tout, je veux aussi extraire du nom du fichier les groupes qui contiennent "IE6", "IE7", "IE8", etc pour obtenir par exemple à partir de IE8_WindowsServer2003-KB2722913-x86-ENU.exe ou WindowsServer2003-KB2722913-x86-ENU_IE8.exe le résultat invariable suivant :
Citation:
KB2722913_IE8
Et c'est la que les problèmes commencent car lorsque je rajoute les groupes (IE[0-9]+)? et ([_-])? dans mon expression régulière, ceux-ci ne sont pas trouvés dans le résultat :-(
Apparemment, les .* dans l'expression régulière étant la source du problème.
J'ai cherché du côté des lookahead/lookbehind et autre lookaround (http://www.regular-expressions.info/lookaround.html) mais je ne maîtrise pas ces aspects et je n'ai pas trouvé la bonne expression tout seul...

Mon expression régulière (à cet instant) qui récupère IE[0-9]+[-_] au début de la chaine, mais pas ailleurs :
Code :
^(IE[0-9]+)?([-_])?.*(KB[0-9]+)[-_]?(V[0-9]+)?.*([-_])?(IE[0-9]+)?.*$
Remplacé par :
Citation:
$3$4$2$1$5$6
Résultat (à partir de WindowsServer2003-KB2722913-x86-ENU_IE8.exe):
Citation:
KB2722913
Alors que je souhaiterai obtenir le résultat suivant:
Citation:
KB2722913_IE8

D'avance merci !
jaudouy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/11/2012, 13h12   #2
CosmoKnacki
Membre habitué
 
Avatar de CosmoKnacki
 
Homme
Inscription : mars 2009
Messages : 106
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations forums :
Inscription : mars 2009
Messages : 106
Points : 130
Points : 130
Bonjour,

tu peux essayer ça:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$test=array(
    "IE8_WindowsServer2003-KB2722913-x86-ENU.exe",
    "WindowsServer2003-KB2722913-x86-ENU_IE8.exe",
    "IE_WindowsServer2003-KB2722913-v2-x86-ENU.exe",
    "WindowsServer2003-KB2722913-x86-ENU_IE10.exe" );
 
$patt="/^(?:(IE\d{0,2}?)(_))?.*?-(KB\d*(?:[-_]v\d)?).*?(?:(_IE\d{0,2}?))?\.exe$/i";
$repl="$3$2$1$4";
 
echo "<br/><br/>";
 
print_r($test);
 
echo "<br/><br/>";
 
print_r(preg_replace($patt, $repl, $test)); ?>
Aprés tu peux améliorer, notamment en réduisant les zones d'incertitudes (par exemple, pourquoi mettre un (.*) gourmand en ressource alors qu'on pourrai mettre (Windows(Server2003|XP)) à la place)
CosmoKnacki est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/12/2012, 09h54   #3
jaudouy
Futur Membre du Club
 
Inscription : novembre 2005
Messages : 26
Détails du profil
Informations forums :
Inscription : novembre 2005
Messages : 26
Points : 17
Points : 17
Je n'avais pas vu ta réponse, merci de t'être penché sur mon cas, cela m'a permis de comprendre certaines subtilités et d'optimiser l'expression avec tes conseils.
J'ai pu trouver LA bonne expression régulière !

Code :
^(?:(IE\d+)([_\-\.]))?(?:Windows(?:Server2003|XP|\d+[_\-\.]\d+)[_\-\.])+(?:(KB\d+)(?:[_\-\.](v\d+))?)(?:[_\-\.]x(?:86|64))(?:[_\-\.](?:ENU|FRA))?(?:([_\-\.]IE\d+))?\.(?:exe|msu)$
Retourne maintenant selon les cas:
KB2722913 (pas de "v2" ni de "IE8")
KB2722913_IE8 (pas de "v2" mais présence d'un "IE8" quelque soit son emplacement)
KB2722913v2 (présence d'un "v2" mais pas de "IE8")
KB2722913v2_IE8 (présence d'un "v2" et d'un "IE8" quelque soit son emplacement)


Encore merci pour ton aide et tes conseils très appréciés !

Edit: petite correction: "(?:[_\-\.](v\d+)?)" corrigé en "(?:[_\-\.](v\d+))?"
jaudouy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/12/2012, 14h13   #4
CosmoKnacki
Membre habitué
 
Avatar de CosmoKnacki
 
Homme
Inscription : mars 2009
Messages : 106
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations forums :
Inscription : mars 2009
Messages : 106
Points : 130
Points : 130
À la bonne heure.

Il n'est pas utile d'échapper le point à l'intérieur d'une classe de caractère (car il est juste considéré comme le caractère point), ni le tiret si tu le place à la fin (car à cette place l'interprêteur sait qu'il n'est pas là pour délimiter un intervalle de caractères) donc tu peux remplacer [_\-\.] par [_.-].

Autre chose, et sauf information contraire, rien ne te dit que le correctif porte sur une version spécifique d'IE. Dans ce cas IE_WindowsServer2003-KB2722913-v2-x86-ENU.exe ne sera pas `matché` par ton expression à cause du IE\d+ qui exige au moins 1 chiffre. Donc mieux vaut le remplacer par IE\d* ou par IE\d{0,2}. (en supposant qu'il n'y ait pas de patch pour la version 5.5 d'IE)

Bonne continuation.
CosmoKnacki est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/12/2012, 14h46   #5
jaudouy
Futur Membre du Club
 
Inscription : novembre 2005
Messages : 26
Détails du profil
Informations forums :
Inscription : novembre 2005
Messages : 26
Points : 17
Points : 17
Oui d'ailleurs, j'ai carrément remplacé par [\W_].
Concernant IE je suis d'accord sur le principe même si dans la réalité et en remontant jusqu'en 2008, il y a toujours eu indiqué la version: IE6 IE8 IE9, etc

Bonne continuation !
jaudouy est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 10h13.


 
 
 
 
Partenaires

Hébergement Web