Question Regex pour newbie

Plus d'informations
il y a 16 ans 11 mois #4453 par Gabriel
Regex pour newbie a été créé par Gabriel
hello

Je cherche un petit coup de main pour utiliser correctement un regex.
Le besoin:
a. Recuperer le nom d'un formulaire qui se trouve dans un fichier XML mal formaté. On ne peut pas utiliser l'import XML (j'ai essayé , il y a des caracteres que l'import XML ne comprend pas. Et on ne doit pas modifier le fichier)
b. il me faut donc parser le fichier, trouver la bonne ligne, puis dans cette ligne extrainre la bonne valeur. Sortir une log avec le vrai nom du fichier et le nom du rapport en face.
c. les données (petit exemple de données a parser):
[code:1]<LocalContainerPreFilter Apply=\"true\" Description=\"Recurse All Levels\" ClassID=\"{A3742FB8-E657-3BF9-B681-92D23A5A2467}\" RecursionLevel=\"536870912\"/>
</ScopeItem>
</ScopeItems><GlobalPreFilters/>
</ObjectScope>
<Reports><Report FilterString=\"\" ReportCreator=\"\" FilterObject=\"\" ReportOptions=\"\" CollectionMethod=\"0\" DateRange=\"0\" Mode=\"0\" ChangeHistoryFromLow=\"766449792\" ChangeHistoryFromHigh=\"29985673\" ChangeHistoryToLow=\"766449792\" ChangeHistoryToHigh=\"29985673\" Screen=\"0\" StandardLayout=\"1\" PortraitLayout=\"1\" AppendDateStamp=\"0\" OneFilePerPage=\"0\" File=\"1\" FileType=\"4\" AllowFieldChanges=\"true\" AllowGrouping=\"true\" AllowTrackChanges=\"true\" FilteringAllowed=\"false\" ObjectClassID=\"-1\" Range=\"0\" RangeType=\"0\"><ReportInformation ID=\"{00000000-0000-0000-0000-000000000149}\" Name=\"EQD Domain Summary\" Category=\"4\"/>
</Report>
</Reports>[/code:1]
d. la données a recuperer dans l'exemple est Name=\"EQD Domain Summary\"
e. la regex que j'ai trouvé [code:1](?<=Name=\"«»)([^\"]+)[/code:1]
elle me donne exactement le champs mais il faut seulement l'executer dans la ligne qui commence \"Report FilterString\" (car le champ name= apparait plusieurs fois et seul celui de cette ligne m'interesse).
f. ce que j'essaie de taper pour simplement recuperer le champs (et qui marche pas)
[code:1]$Chemin = c:\temp
$RegExA = (?<=Name=\"«»)([^\"]+)
gci $Chemin -recurse -filter *.inf | foreach { [regex]::match($_,'$RegExA).value }[/code:1]
l'idee de la commande est de simplement pour chaque fichier m'afficher dans la console la valeur qui m'interesse. j'ai regarder a droite a gauche et a force de modifier ce bout de code je sais meme plus si ca vient de ma regex ou de mon Foreach (je soupgonne quand meme beaucoup mon foreach que j'ai tripoter dans tous les sens...

Si l'un de vous peu m'eclairer...:blush:

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 16 ans 11 mois #4461 par Laurent Dardenne
Réponse de Laurent Dardenne sur le sujet Re:Regex pour newbie
tonic8 écrit:

e. la regex que j'ai trouvé [code:1](?<=Name=\"«»)([^\"]+)[/code:1]

Je ne comprends pas la première partie, tu peux m'expliquer ?
tonic8 écrit:

elle me donne exactement le champs mais il faut seulement l'executer dans la ligne qui commence \"Report FilterString\" (car le champ name= apparait plusieurs fois et seul celui de cette ligne m'interesse).

Après pas mal d'essais
[code:1]
$r='<Report FilterString=.*[^>]><ReportInformation.*[^>] Name=\"(.*[^>])\".*[^>]=.*/>'
gc test.inf | Where { $_ -match $r }|% {$matches}
[/code:1]
sur les lignes précisées plus celles-ci:

<Reports><Report FilterString=\"\" ><ReportInformation /><Report FilterString=\"\"><ReportInformation Name=\"V5 EQD Domain Summary\" Test=\"r\"/>
<Reports><Report FilterString=\"\" ><ReportInformation /><Report FilterString=\"\"><ReportInformation FullName=\"V6 ne doit pas matché\" Test=\"r\"/>
<Tests><Test FilterString=\"\" ><TestReportInformation /><Test Name=\"V7 ne doit pas matché\" />

Je ne pense pas que ce soit la meilleure solution mais elle semble répondre au besoin.
Pour le moment elle ne fonctionne QUE SI chaque ligne du fichier xml ne contient qu'un élément \"Report...\".

Pour ce type d'exercice il faut connaitre les diverses construction possible du fichier. Dans ton cas j'ai un doute, mais toi seul peut le savoir. C'est à dire, si le fichier xml est mal formaté il faut être sûr qu'il le soit tjr de la même manière ( cohérent dans l'erreur en quelque sorte :P ).

Et sinon tu n'as pas la possibilité de demander une correction auprès de l'émetteur de ce fichier, plutot que t'adapter au problème ?

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 16 ans 11 mois #4463 par Gabriel
Réponse de Gabriel sur le sujet Re:Regex pour newbie
Merci Laurent pour ton aide.

Alors le mauvais formatage est qu'un certain nombre de caractere a l'interieur des champs XML sont pas correctement formaté:
1. quand je fait l'import dans une variable voila ce que ca donne:
[code:1]
[xml] $a = gc \"toto.inf\"
Cannot convert value \"System.Object[]\" to type \"System.Xml.XmlDocument\". Error: \"'', hexadecimal value 0x07, is an invalid character. Line 28, position 86.\"
At line:1 char:9
+ [xml] $a <<<< = gc \"toto.inf\"[/code:1]

2. en regardant le fichier il est codé en ANSI et le caractere qui apparait bizarre est au milieu du champs. j'utilise notepad++ et c'est la premiere fois que je vois ce symbole (dans le fichier attaché le BEL)

3. la ou je n'ai pas ete clair... comme je debute dans les regex (je sais c'est pas la premiere fois que je le dit dans ce forum :whistle: ) je me suis concentré sur la valeur que je veux recuperer c'est a dire la valeur du champs Name (d'ou le regex en debut de post).
ce champs Name apparait plusieurs fois dans le fichier, mais la ligne qui m'interesse il y en a qu'une et c'est celle qui commence par \"Report FilterString=\"

4. l'appli qui crée les fichier est un progiciel, et il sait parfaitement utiliser ses propres fichiers. Donc coté correction j'aurais du mal à leur demandé...

5. pourquoi je fais ca c'est que l'appli lors de la creation du fichier demande le nom du rapport, elle crée le fichier inf avec ce nom et renseigne le champs \"Name=\" de la ligne avec le meme nom.
Mais ensuite cette appli, lorsqu'on renomme le rapport dans l'appli, elle ne modifie QUE le champs \"Name=\" et plus le nom du fichier. Résultat quand il s'agit de backuper les fichiers et qu'on ne veut sauvegarder que les bons, on ne peut pas s'appuyer sur le nom des rapports dans l'appli, car les fichiers physiques ont leur nom disjoint du nom du rapport qui se trouve dedans.

6. là ou j'intervient c'est que je dois recuperer le nom du rapport dans le fichier et renommer le fichier en consequence. L'appli n'utilise pas le nom du fichier elle parse tous les fichier dans le repertoire et son arborescence...

7. Ma petite regex doit etre bonne pour avoir la valeur du champs si je ne parse qu'une seule ligne. Ce qui dans mon cas ne me sert pas. Desolé de la confusion provoquée.

8. l'objectif est donc de parser tous les fichiers *.inf, de recuperer la valeur du champs \"Name=\" dans la ligne contenant \"Report FilterString=\", ensuite je fais une moulinette soit pour stocker la valeur recuerper avec le nom du fichier en face, soit renommer. sur cette derniere partie je sais plus ou moins bien faire mais je me debrouille. C'est l'extraction de la valeur qui me pose soucis.

Merci encore pour ton aide. <br><br>Message édité par: tonic8, à: 25/03/09 13:15
Pièces jointes :

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 16 ans 11 mois #4468 par Laurent Dardenne
Réponse de Laurent Dardenne sur le sujet Re:Regex pour newbie
tonic8 écrit:

Alors le mauvais formatage est qu'un certain nombre de caractere a l'interieur des champs XML sont pas correctement formaté:

Sont-ce toujours les mêmes ?
tonic8 écrit:

j'utilise notepad++ et c'est la premiere fois que je vois ce symbole (dans le fichier attaché le BEL)

C'est le caractère ascii 7, signal sonore. Saisie dans la console control-g puis enter.
Notepad t'indique pas là que c'est un caractère de control.
Avant d'aller plus loin, suite à ta réponse, ne penses-tu pas qu'une correction de ces caractères de contrôle, dans un fichier temporaire, simplifierais le pb ?
Par exemple à l'aide la function proposée ici :
powershell-scripting.com/index.php?optio...;id=4261&catid=5
Si toutefois la manipulation de XML/XPath ne te pose pas de pb particulier.

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 16 ans 11 mois #4479 par Gabriel
Réponse de Gabriel sur le sujet Re:Regex pour newbie
Ben disons que je voulais vraiment le faire via les regex pour comprendre/apprendre les regex.

Et l'avantage c'est que je ne pase par l'ecriture d'un fichier temporaire, qui peut toujours poser probleme (pas assez de place, ou le fichier temp existe deja et autre)...

Je vais regarder tout de meme ta solution.

Merci pour ton aide.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 16 ans 11 mois #4481 par Laurent Dardenne
Réponse de Laurent Dardenne sur le sujet Re:Regex pour newbie
tonic8 écrit:

Ben disons que je voulais vraiment le faire via les regex pour comprendre/apprendre les regex.

Bonne approche, mais faut savoir que c'est un apprentissage sur le long terme.De mon coté je dirais que je connais un peu les regex, et c'est peut-être, à mon niveau, le sujet plus le difficile à appréhender que j'ai rencontré en informatique.
Je te conseille d'investir dans ce bouquin, Maîtrise des expressions régulières .
tonic8 écrit:

Je vais regarder tout de meme ta solution.

Après réflexion elle ne répond pas vraiment au besoin, c'était l'idée du filtre que je voulais mettre en avant.
tonic8 écrit:

Merci pour ton aide.

De rien.

Sinon que donne la regex que je t'ai proposée ?

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.119 secondes
Propulsé par Kunena