[R] Conserver ce qui est concerné par la regex et enlever le reste

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
JulienBoul
Niveau 4
Niveau 4
Messages : 82
Enregistré le : ven. 04 déc. 2015 13:55
Status : Hors ligne

[R] Conserver ce qui est concerné par la regex et enlever le reste

#1

Message par JulienBoul »

Question du soir, bonsoir.

Avec Orax, on a avancé sur l'isolation des variables désirées avec la regex suivante:
(?m)^([^ ]+) ([^ ]+) (.+?)(?:\s*\.\s)+0,00
Pour ma part, j'ai travaillé aujourd'hui sur l'intégration de ces variables dans un tableau avec le script suivant (non fonctionnel):
$Var1 = FileRead (@ScriptDir&"\temp\858792101741_ListePieces.txt")
$aArray = StringRegExp($Var1, "(?m)^([^ ]+) ([^ ]+) (.+?)(?:\s*\.\s)+0,00", 3)

; crée un tableau sous la forme :
; *------------------------------------------------------*
; | Numéro | référence technique | Description
Global $aNumLigne[UBound($aArray) /3][3]

$j = 0
For $i = 0 To UBound($aArray) / 3 - 1
    $aNumLigne[$i][0] = $aArray[$j + 2]
    $aNumLigne[$i][1] = $aArray[$j + 1]
   $aNumLigne[$i][2] = $aArray[$j]
    $j += 2
Next

For $i = 0 To UBound($aNumLigne) - 1
msgbox("","",$aArray[1][1]) ; test pour vérifier la valeur de la ligne 2 croisée colonne 2 également
Next
Pouvez vous m'aider à créer un nouveau fichier avec les données de type

Code : Tout sélectionner

1000 481010582876 PORTE ASS. GR
1001 480120101448 CHARNIERE SCREW MINI2
1170 481949878366 AVM141-Poignée pour plat Crisp 
etc.
Voici le document initial.
N° Référence Description Qté Commentaire
1000 481010582876 PORTE ASS. GR. . . . . . . . . . 0,00
1001 480120101448 CHARNIERE SCREW MINI2. . . . . . 0,00
1170 481949878366 AVM141-Poignée pour plat Crisp . 0,00
1300 480120101791 CAME PLATE. . . . . . . . . . . 0,00
1301 480120101451 LEVIER. . . . . . . . . . . . . 0,00
1302 480120101452 SUPPORT. . . . . . . . . . . . . 0,00
1303 481231038739 INTERRUPTEUR + INTERS . . . . . 0,00
1304 481231038743 PION PORTE. . . . . . . . . . . 0,00
2460 480120101453 PLAT CRISP SMALL. . . . . . . . 0,00
2550 481246678412 PLATEAU TOURN. TOURNANT 25 cm. . 0,00
2640 481010422369 PLATEAU TOURN. CERCHIO MIBI GR/. 0,00
2641 481946238767 RAIL PLAT TOURN. . . . . . . . . 0,00
3010 481010582875 DOSSERET C+ IXL GR Mini2. . . . 0,00
3320 480120100884 POUSSOIR C+1. . . . . . . . . . 0,00
3321 480120100885 POUSSOIR C+2. . . . . . . . . . 0,00
3322 480120100782 POUSSOIR HINGES. . . . . . . . . 0,00
3500 481010364177 AFFICHEUR APRÈS: 46/10. . . . . 0,00
4040 481213158813 MAGNETRON. . . . . . . . . . . . 0,00
4120 480120100336 TRANSFORMATEUR HT. . . . . . . . 0,00
4200 481212158159 CONDENSATEUR. . . . . . . . . . 0,00
4220 481236158419 MOTEUR TT. . . . . . . . . . . . 0,00
4260 481221838323 DIODE AT. . . . . . . . . . . . 0,00
4400 480120101953 MOTEUR. . . . . . . . . . . . . 0,00
4520 480120101407 ELEM. CHAUFFANT 350W 115V. . . . 0,00
4521 481225998463 ROTISSOIRE. . . . . . . . . . . 0,00
4522 480120101247 PROTECTION GRILL. . . . . . . . 0,00
4800 481068977341 LIMANDE AFFICHEUR - PLAT PUISS. 0,00
4900 480120101164 CORDON SECTEUR. . . . . . . . . 0,00
5000 481010577756 PLATINE CONTROLE FREJA2 ACU GR-. 0,00
5610 480120100531 THERMOSTAT 130C. . . . . . . . . 0,00
6330 480120101578 INTERRUPTEUR. . . . . . . . . . 0,00
6520 481213418008 LAMPE. . . . . . . . . . . . . . 0,00
Micro-ondes encastrable - 858792101741 11/11/2016
Micro-ondes encastrable - Whirlpool - Micro-ondes encastrable - 858792101741 - AMW921IXL

1/2

7740 481244229206 PLAQUE MICA DE CAVITE. . . . . . 0,00
7741 481249148016 DOIGT INT.CAVITE. . . . . . . . 0,00
9220 481953268686 BAGUE. . . . . . . . . . . . . . 0,00
9300 481249268172 RESSORT TENSION LEVIER. . . . . 0,00
Micro-ondes encastrable - 858792101741 11/11/2016
Micro-ondes encastrable - Whirlpool - Micro-ondes encastrable - 858792101741 - AMW921IXL

2/2


Par curiosité, et c'était l'objectif de mon script à l'origine, pouvez vous m'expliquer comment "appeler" un tableau 2D svp? J'ai consulté l'aide et je n'ai trouvé aucun exemple annoté qui me permette de bien comprendre. A la base j'ai essayé en mixant plusieurs exemples de batir mon code mais ça ne fonctionne pas.

D'avance merci aux codeurs du soir :-p
Modifié en dernier par JulienBoul le mer. 16 nov. 2016 09:10, modifié 1 fois.
Avatar du membre
orax
Modérateur
Modérateur
Messages : 1479
Enregistré le : lun. 23 mars 2009 04:50
Localisation : ::1
Status : Hors ligne

Re: [..]

#2

Message par orax »

 ! Message de : orax
[..]
:shock:
— Dupond : Ce titre est vide de sens !
— Dupont : Je dirais même plus, ce titre est vide tout court !
#include <Array.au3>

$Var1 = FileRead(@ScriptDir & "\temp\858792101741_ListePieces.txt")
$aArray = StringRegExp($Var1, "(?m)^([^ ]+) ([^ ]+) (.+?)(?:\s*\.\s)+0,00", 3)
_ArrayDisplay($aArray)

; crée un tableau sous la forme :
; *------------------------------------------------------*
; | Numéro | référence technique | Description
Global $aNumLigne[UBound($aArray) / 3][3]

$j = 0
For $i = 0 To UBound($aArray) - 1 Step 3
   $aNumLigne[$j][0] = $aArray[$i + 2]
   $aNumLigne[$j][1] = $aArray[$i + 1]
   $aNumLigne[$j][2] = $aArray[$i]
   $j += 1
Next

_ArrayDisplay($aNumLigne)

For $i = 0 To UBound($aNumLigne) - 1
   ; [!] le tableau 2D c'est $aNumLigne et non pas $aArray
   MsgBox("", "", $aNumLigne[1][1]) ; test pour vérifier la valeur de la ligne 2 croisée colonne 2 également
Next
Peut-être que StringRegExpReplace serait plus pratique.
https://regex101.com/r/UZOoPQ/1 Voir la partie SUBSTITUTION.
De petits détails peuvent faire toute la différence. — Quand la boule de neige commence à rouler… poussez-la. (Columbo)
JulienBoul
Niveau 4
Niveau 4
Messages : 82
Enregistré le : ven. 04 déc. 2015 13:55
Status : Hors ligne

Re: [R] Conserver ce qui est concerné par la regex et enlever le reste

#3

Message par JulienBoul »

Oulalaaaaaaaaa, quand je me suis co ce matin sur le site, je vois JulienBoul en dessous d'un titre vide (avec les belles balises quand même lol). Sorry j'ai eu un bug serveur SQL je sais plus trop quoi hier après avoir édité mon titre, j'aurai du verifier mais trop pressé de rentrer chez moi me poser au coin du feu ^^.
Le voici réédité, autant pour moi.

Tip top ton code Orax, j'était pas si loin, mais les tableaux c'est encore un peu abstrait, j'arrive a en créer simplement, dans le code, mais quand il s'agit d'intégrer un document déjà existant, avec des Expressions Régulières d'autant plus, j'avoue que j'm'y perd vite.
Autant Autoit est un language super abordable pour les non informaticiens, autant pour devenir bon, faut vraiment une super rigueur et des bases très solides... Espérons que ça viendra...

J'ai apporté quelques modifications, si ça peut aider certains à alimenter leur code dans le futur.
$Var1 = FileRead(@ScriptDir & "\temp\854298729820_ListePieces.txt")
$aArray = StringRegExp($Var1, "(?m)^([^ ]+) ([^ ]+) ([^ ]+) (.+?)(?:\s*\.\s)+0,00", 3)
;_ArrayDisplay($aArray) ; présente le tableau brut avec 4 lignes par pièce

; crée un tableau sous la forme :
; *------------------------------------------------------*
; | Numéro | référence technique | Description
Global $aNumLigne[UBound($aArray) / 4][4]
$j = 0
For $i = 0 To UBound($aArray) - 1 Step 4
    $aNumLigne[$j][0] = $aArray[$i]    ;crée la colonne 1
    $aNumLigne[$j][1] = $aArray[$i + 1]   ;crée la colonne 2
    $aNumLigne[$j][2] = $aArray[$i + 2]   ;crée la colonne 3
   $aNumLigne[$j][3] = $aArray[$i + 3] ;crée la colonne 4
    $j += 1
Next

;_ArrayDisplay($aNumLigne) ; présente le tableau ordonné avec 1 ligne et 4 colonnes par pièce.

For $i = 0 To UBound($aNumLigne) - 1
   ; MsgBox("", "", $aNumLigne[$i][1]) ; vérification de la valeur $i dans la colonne 1 pour cet exemple.
$fh = FileOpen(@ScriptDir & "\temp\854298729820_ListePieces_modif.txt", 1)
If $fh = -1 Then SetError(1, 0, 0)
Local $iWriteFile = FileWriteLine($fh, $aNumLigne[$i][0]&$aNumLigne[$i][1]&";"&$aNumLigne[$i][2]&";"&$aNumLigne[$i][3]) ; dans le fichier de base il y a un espace au milieu de la première variable.
Local $iRet = FileClose($fh)
If $iWriteFile = -1 Then SetError(2, $iRet, 0)
_ReplaceStringInFile (@ScriptDir & "\temp\854298729820_ListePieces_modif.txt",@CRLF&chr("012"),""); supprime le caractère ascii 012 et le saut de ligne présents dans le fichier initial
Next
Énième merci Orax, pas de travail maison pour ce soir ;-)
@+, Julien.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [R] Conserver ce qui est concerné par la regex et enlever le reste

#4

Message par mikell »

Pouvez vous m'aider à créer un nouveau fichier avec les données de type
C'est plus simple en commençant par là, ça permet une solution alternative :mrgreen:

Code : Tout sélectionner

#Include <Array.au3>
#include <File.au3>

; création du nouveau fichier
FileWrite("test_new.txt", StringRegExpReplace(FileRead("test.txt"), '(?m)(^(?!\d{4}).*\R?)|([.\h]+0,00)', "") )

; création de l'array (si nécessaire) en utilisant un fichier temporaire jetable
FileWrite(@tempdir & "\tmp.txt", StringRegExpReplace(fileread("test_new.txt"), '(?m)(?<=\d{4}|\d{12})\s', "§") )
Local $array
_FileReadToArray(@tempdir & "\tmp.txt", $array, 0, "§")
FileDelete(@tempdir & "\tmp.txt")
_ArrayDisplay($array)
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
JulienBoul
Niveau 4
Niveau 4
Messages : 82
Enregistré le : ven. 04 déc. 2015 13:55
Status : Hors ligne

Re: [R] Conserver ce qui est concerné par la regex et enlever le reste

#5

Message par JulienBoul »

Salut mikell,
FileWrite(@ScriptDir & "\temp\test_new.txt", StringRegExpReplace(FileRead(@ScriptDir & "\temp\854298729820_ListePieces.txt"), '(?m)(^(?!\d{3} \d{1}).*\R?)|([.\h]+0,00)', "") )
FileWrite(@ScriptDir & "\temp\tmp.txt", StringRegExpReplace(fileread(@ScriptDir & "\temp\test_new.txt"), '(?m)(?<=\d{3} \d{1}|\d{12})\s', ";"))
Je suis convaincu par la concision de ton code. Néanmoins, j'ai oublié de préciser que le fichier de base est standardisé mais peut contenir des petites modifications en fonction de la marque.
Ainsi, je me retrouve avec un fichier tel quel celui ci:
► Afficher le texte
Et je n'arrive pas a supprimer le premier espace de ma ligne, peux tu me guider au niveau de l'expression régulière stp?
Je pense avoir une partie de l'expression à intégrer mais j'arrive pas à articuler:
(?m)^\d{1,}([^\S])\d{1,}
D'avance merci, je laisse en résolu sachant qu'on déborde un peu du sujet principal et que la réponse a été donnée plus haut.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [R] Conserver ce qui est concerné par la regex et enlever le reste

#6

Message par mikell »

j'ai oublié de préciser que le fichier de base est standardisé mais peut contenir des petites modifications en fonction de la marque
Tu as parfaitement décrit la principale cause d'échec des expressions régulières, qui sont d'une rigueur de majordome britannique, manquent totalement d'humour et détestent les "petites modifications" :mrgreen:

Si le fichier "peut contenir des petites modifications" il n'est donc PAS standardisé (enfin, pas tout à fait)
Donc il y a un prétraitement à faire pour pouvoir traiter avec le même regex les fichiers des posts #1 et #5
comme tu l'as noté, il faut supprimer le 1er espace, SI la ligne démarre avec 3 chiffres seulement
Ce code marche pour les 2 fichiers, j'ai un peu plus détaillé et commenté
#Include <Array.au3>
#include <File.au3>

$orig = FileRead("test.txt")
; élimine les lignes qui ne commencent pas par 3 chiffres ET les fins de ligne indésirables
$tmp = StringRegExpReplace($orig, '(?m)(^(?!\d{3}).*\R?)|([.\h]+0,00)', "")
; élimine le 1er espace de la ligne, seulement s'il est précédé d'exactement 3 chiffres
$tmp = StringRegExpReplace($tmp, '(?m)(?<=^\d{3})\s', "")
; création du nouveau fichier
FileWrite("test_new.txt", $tmp)

#cs
; création de l'array (si nécessaire) en utilisant un fichier temporaire jetable
FileWrite(@tempdir & "\tmp.txt", StringRegExpReplace($tmp, '(?m)(?<=^\d{4}|\d{12})\s', "§") )
Local $array
_FileReadToArray(@tempdir & "\tmp.txt", $array, 0, "§")
FileDelete(@tempdir & "\tmp.txt")
_ArrayDisplay($array)
#ce
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
JulienBoul
Niveau 4
Niveau 4
Messages : 82
Enregistré le : ven. 04 déc. 2015 13:55
Status : Hors ligne

Re: [R] Conserver ce qui est concerné par la regex et enlever le reste

#7

Message par JulienBoul »

Haha, "
(?m)(?<=^\d{3})\s
était l'expression régulière que je cherchais pour regrouper ma première chaine de caractère. J'ai tenté de bidouiller ("Mon dieu, mais tu n'as rien compris? On ne "bidouille" pas avec les expressions régulières !!!" Bon, je fais des tests, c'est comme cela que ça finira par rentrer !) sur la base de ta formule pour sélectionner les deux premiers espaces de la ligne, et les remplacer par des points virgule (préparation du CSV), mais y'a une faille, ça selectionne "l'espace qui suit au moins 4 chiffres". Ainsi, si j'ai un intitulé qui comporte cette disposition, ça va bloquer.
Ne serait ce pas plus judicieux de sélectionner les deux premiers espaces de chaque ligne plutôt?
$orig = FileRead(@ScriptDir & "\temp\854298729820_ListePieces.txt")
; élimine les lignes qui ne commencent pas par 3 chiffres ET les fins de ligne indésirables
$tmp = StringRegExpReplace($orig, '(?m)(^(?!\d{3}).*\R?)|([.\h]+0,00 )', "")
; élimine le 1er espace de la ligne, seulement s'il est précédé d'exactement 3 chiffres
$tmp = StringRegExpReplace($tmp, '(?m)(?<=^\d{3})\s', "")
; création du fichier final remplaçant les deux premiers espaces par un ";" (format csv)
FileWrite(@ScriptDir & "\temp\854298729820_ListePieces_final.txt", StringRegExpReplace($tmp, '(?m)(?<=\d{4})\s', ";") )
Voici mon fichier final
► Afficher le texte
Et je viens de me rendre compte du point virgule en fin de ligne 2430... D'ou l'importance de changer de méthode pour positionner mes points virgules :-D

Je tiens également à préciser que le fichier de base sera toujours standardisé. En fonction de la marque (tous les 2000 fichiers), le standard risque de changer, on peut avoir des lettres dans la ref technique etc, mais la colonne 1 et la colonne 2 auront toujours la même structure donc ça va encore...
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [R] Conserver ce qui est concerné par la regex et enlever le reste

#8

Message par mikell »

Et je viens de me rendre compte du point virgule en fin de ligne 2430
D'où l'intérêt d'être précis dans l'expression :

Code : Tout sélectionner

FileWrite(@ScriptDir & "\temp\854298729820_ListePieces_final.txt", StringRegExpReplace($tmp, '(?m)(?<=^\d{4}|\d{12})\s', ";") )
Maintenant, TU connais le contenu de tes fichiers et leurs variations possibles, mais pas moi... les seules bases que j'ai sont les fichiers originaux que tu as fourni, et avec eux mon code précédent marche correctement :

Code : Tout sélectionner

$orig = FileRead("test0.txt")
; élimine les lignes qui ne commencent pas par 3 chiffres ET les fins de ligne indésirables
$tmp = StringRegExpReplace($orig, '(?m)(^(?!\d{3}).*\R?)|([.\h]+0,00)', "")
; élimine le 1er espace de la ligne, seulement s'il est précédé d'exactement 3 chiffres
$tmp = StringRegExpReplace($tmp, '(?m)(?<=^\d{3})\s', "")
; création du nouveau fichier
$tmp = StringRegExpReplace($tmp, '(?m)(?<=^\d{4}|\d{12})\s', ";")
msgbox(0,"", $tmp)
Après, bin il est évident qu'une variation dans le format des fichiers peut nécessiter une adaptation de l'expression :wink:
Cela dit il y a généralement plusieurs manières d'aborder un problème. Orax en a montré une, donc forcément (en bon pervers) j'en ai montré une autre. A toi de faire ton tri dans tout ce brol en fonction de ce que tu as à traiter et des résultats souhaités :mrgreen:
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
JulienBoul
Niveau 4
Niveau 4
Messages : 82
Enregistré le : ven. 04 déc. 2015 13:55
Status : Hors ligne

Re: [R] Conserver ce qui est concerné par la regex et enlever le reste

#9

Message par JulienBoul »

Hello,

En fait lorsque je copie colle mon fichier sur le forum, il perd une partie de sa mise en page, nottament à cause d'un caractère ASCII 012 qui ne peut être copié sur le forum. Vous m'avez suffisament avancé pour que je puisse extraire les données que je veux, c'était surtout parce que j'aime pas avoir un doute entre 2 codes et je préfère l'optimiser que j'insistait :)
C'est top, merci à vous deux, j'ai en effet plusieurs exemples de regex et j'me suis fait une petite bibliothèque d'exemples, je pourrais les mixer/modifier pour les prochaines fois. Pis les sites de simulation, ça aide vachement !

A+
Répondre