[..] Expressions régulières : Comparer et remplacer

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
Pyrithe
Niveau 1
Niveau 1
Messages : 12
Enregistré le : lun. 03 oct. 2011 11:35
Status : Hors ligne

[..] Expressions régulières : Comparer et remplacer

#1

Message par Pyrithe »

Bonjour tout le monde.

Je cherche à me faciliter le travail en créant un petit script, qui aurait pour fonction le découpage de chaines (codes barres).
En gros, la finalité c'est de définir une douzaine de motifs correspondants à mes types de codes barres différents.
Je souhaite ensuite comparer un code barre saisi (via une input box) à mes différents motifs afin de déterminer auquel il correspond, et ensuite le découper en fonction.

J'ai cependant du mal à "articuler" tout ca. Je ne suis pas du tout familier d'AutoIt, ni du scripting en général.
Je ne demande évidemment pas qu'on me fournisse du code tout fait, mais si quelques âmes charitables voulaient bien m'accompagner sur ce projet, ce serait vraiment cool. J'espère ainsi progresser à travers un cas très concret.
Pour commencer, comment construiriez vous ce besoin, et en utilisant principalement quelles fonctions clé?

Merci d'avance à ceux qui voudront bien m'accompagner un peu! :)
Oversid3
Niveau 3
Niveau 3
Messages : 45
Enregistré le : jeu. 29 janv. 2015 11:20
Status : Hors ligne

Re: [..] Expressions régulières : Comparer et remplacer

#2

Message par Oversid3 »

Bonjour et bienvenu !

Je t'avoue que ce n'est pas trés clair pour le moment :/

Donc tes "codes barres" sont sous quelles forme ? Suite numerique ?
Quelle est cette histoire de motifs ?

Bref dispo pour aider mais il va falloir detailler un peu plus :)
Avatar du membre
jguinch
Modérateur
Modérateur
Messages : 2515
Enregistré le : lun. 14 févr. 2011 22:12
Status : Hors ligne

Re: [..] Expressions régulières : Comparer et remplacer

#3

Message par jguinch »

comme l'a dit Oversid3, il faut éclaircir un peu cette histoire de motifs.
Il faut énoncer les les choses clairement (le plus clairement possible, sans ajouter des trucs toutes les 5 minutes).
Pour ça tu peux nous mettre des exemples de chaîne CB avec le résultat attendu, et nous expliquer ce que tu as besoin de faire avec le code barre.
Le script, ça fait gagner beaucoup de temps... à condition d'en avoir beaucoup devant soi !
Pyrithe
Niveau 1
Niveau 1
Messages : 12
Enregistré le : lun. 03 oct. 2011 11:35
Status : Hors ligne

Re: [..] Expressions régulières : Comparer et remplacer

#4

Message par Pyrithe »

Effectivement, ce n'est pas clair...

Voilà pour éclaircir le problème :

Je veux traiter des codes barres de produits, qui sont des chaines numériques.
Selon leur "motif" (qui, il me semble, est le terme français pour les pattern regexp), je cherche à découper cette chaine pour isoler une partie de la chaine.

Par exemple, je rentre ce code barre :
2333333444444

Je souhaite analyser cette chaîne afin de déterminer si elle correspond à un de mes douze motifs (ou pattern).
En l’occurrence, elle va matcher avec "2\d{12}" (une chaîne de 13 caractères commençant par la décimale "2").

Je souhaite ensuite indiquer que, dans ce cas de figure, il faut conserver uniquement les 6 caractères suivant le chiffre deux, qui correspond à mon identifiant d'article. Je devrais donc isoler la chaîne 333333.

Si vous pouviez déjà m'aiguiller en me disant comment vous appréhendez le problème, ca serait bien, car je m'éparpille dans mes recherches et ca ne donne rien au final...
Oversid3
Niveau 3
Niveau 3
Messages : 45
Enregistré le : jeu. 29 janv. 2015 11:20
Status : Hors ligne

Re: [..] Expressions régulières : Comparer et remplacer

#5

Message par Oversid3 »

C'est plutot simple du coup :)

Il va falloir entrer (lire un fichier txt, un excel, ce que tu veux) ton code barre dans une variable et jouer avec.

Voila un exemple :

Code : Tout sélectionner

$Valeur = "2333333444444" ;Ta valeur de base, je ne sais pas comment tu la recupere alors on l'ecrit en dure pour tester


$TailleValeur=StringLen($Valeur) ;a supposer que la taille du code barre soit differente, on la recupere
ConsoleWrite($TailleValeur&@CRLF) ; et on l'ecrit

$PremierChar=StringTrimRight($Valeur, $TailleValeur-1) ;on coupe la chaine pour recuperer le premier char
ConsoleWrite($PremierChar&@CRLF) ;on affiche pour verifier

;On deroule les conditions

If ($TailleValeur="13" and $PremierChar="2") Then ;Si le premier charactere est 2 et 13 au total alors
    $CodeArticle=StringTrimRight($Valeur, 6); On coupe a 7 char
    $CodeArticleFinal=StringTrimLeft($CodeArticle, 1); on vire le premier char
    ConsoleWrite($CodeArticleFinal&@CRLF); resultat final 333333
EndIf

;Et tu enchaine ici avec une autre condition sur le même modele.

If ($TailleValeur="16" and $PremierChar="4") Then
    $CodeArticle=StringTrimRight($Valeur, 8); 
    $CodeArticleFinal=StringTrimLeft($CodeArticle, 1); 
    ConsoleWrite($CodeArticleFinal&@CRLF); 
 
Avatar du membre
orax
Modérateur
Modérateur
Messages : 1479
Enregistré le : lun. 23 mars 2009 04:50
Localisation : ::1
Status : Hors ligne

Re: [..] Expressions régulières : Comparer et remplacer

#6

Message par orax »

Je n'avais pas non plus compris que le terme "motif" faisait référence aux expressions régulières. Je pensais qu'il s'agissait des espèces de traits des codes barres. Image
Si les 12 motifs sont déjà faits tu pourrais utiliser StringRexExp pour tous les vérifier à travers une boucle.
► Afficher le texte
De petits détails peuvent faire toute la différence. — Quand la boule de neige commence à rouler… poussez-la. (Columbo)
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Expressions régulières : Comparer et remplacer

#7

Message par mikell »

Questions subsidiaires :
1) la longueur de la chaîne est constante ou variable ?
2) la même chaîne peut-elle correspondre à plusieurs motifs ?

Si c'est "oui" au 1) alors il faut modifier le pattern du regex
Si c'est "non" au 2) alors là c'est plutôt simple, il suffit de trouver le regex qui va bien :

Code : Tout sélectionner

$sCode = "2333333444444567"
[color=#CC0000]; si la chaine commence par un 2 [b]ET[/b] commence par 13 chiffres,
; alors on garde les 6 chiffres après le 2 du début :[/color]
$sRet = StringRegExpReplace($sCode, '^2(\d{6})\d{6}.*', "$1")
If @extended Then 
    Msgbox(0,"", $sRet)
Else
    Msgbox(0,"", "no match")
EndIf
Si c'est "oui" au 2) alors faut utiliser la méthode d'orax (array et boucle)

Code : Tout sélectionner

$sCode = "2333333444444567"
Global $aPatterns = ["^2(\d{6})\d{6}.*", "23(\d{2})\d{6}.*"]   
[color=#CC0000]; les 2 motifs correspondent, on obtiendra donc 2 résultats différents selon le motif[/color]
For $i = 0 To UBound($aPatterns) - 1
   $sRet = StringRegExpReplace($sCode, $aPatterns[$i], "$1")
   If @extended Then 
       Msgbox(0,"", $sRet)
   Else
       Msgbox(0,"", "no match")
   EndIf
Next
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Pyrithe
Niveau 1
Niveau 1
Messages : 12
Enregistré le : lun. 03 oct. 2011 11:35
Status : Hors ligne

Re: [..] Expressions régulières : Comparer et remplacer

#8

Message par Pyrithe »

Merci à vous pour ces précieuses infos!!

@Oversid3 : Merci, mais ca ne correspond pas tout à fait, je veux vraiment utiliser les expressions régulières, qui colleront mieux à mes besoins (certains patterns sont assez complexes).

@orax : Merci infiniment!! Ca marche parfaitement bien. Je vais essayer d'adapter petit à petit tout ca à mon cas.

@mikell : Mes chaines seront de longueur variable, puisqu'on peut avoir des codes barres sur 13, 14, ou 128 caractères. Mais les patterns permettent de définir le type de code barre. Et non, un code barre devra correspondre à un seul pattern, obligatoirement.


Le but était donc aussi, comme je vous le disais, que je comprenne le truc et que je progresse à travers ce cas pratique.
Du coup, je pense avoir compris que :

Code : Tout sélectionner

Global $aPatterns = ["2\d{12}", "5\d{10}12", "3\d{11}4"]
On définit une variable $aPatterns en tableau.

Code : Tout sélectionner

For $i = 0 To UBound($aPatterns) - 1
sert à créer une boucle, et UBound permet de remonter le nombre de dimensions du tableau?

Par contre j'ai pas compris ton commentaire "; syntaxe plus courte (avec le [0] à la fin) mais si StringRegExp renvoie une erreur, ça plante"

En tous cas, merci à tous de m'aider!!
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Expressions régulières : Comparer et remplacer

#9

Message par mikell »

Pyrithe a écrit :Mes chaines seront de longueur variable, puisqu'on peut avoir des codes barres sur 13, 14, ou 128 caractères.
Dans ce cas il faut mettre dans le regex l'ancre de début de chaîne "^"
Par exemple "2\d{12}" marchera pour $sCode = "abc233333344444456789" mais "^2\d{12}" échouera
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
orax
Modérateur
Modérateur
Messages : 1479
Enregistré le : lun. 23 mars 2009 04:50
Localisation : ::1
Status : Hors ligne

Re: [..] Expressions régulières : Comparer et remplacer

#10

Message par orax »

On pourrait même ajouter $ en plus de ^ => ^2\d{12}$
Pyrithe a écrit :Par contre j'ai pas compris ton commentaire "; syntaxe plus courte (avec le [0] à la fin) mais si StringRegExp renvoie une erreur, ça plante"
Quand l'expression est trouvée, StringRegExp retourne un tableau (array). Avec [0] cela indique qu'on récupère la 1ère case de ce tableau. Dans le cas contraire, si l'expression n'est pas trouvée, StringRegExp ne retournera pas de tableau et "[0]" essayera de récupérer la 1ère d'un tableau inexistant donc : erreur.

Le code suivant plante puisque la variable retournée par StringRegExp n'est pas un tableau.

Code : Tout sélectionner

$sRet = StringRegExp("aaa", "2(\d{6})", 1)[0]
En 2 lignes on pourrait aussi s'écrire comme ça :

Code : Tout sélectionner

$aRet = StringRegExp("aaa", "2(\d{6})", 1)
$sRet = $aRet[0] ; $aRet ne sera pas un tableau donc ça va planter
Mais celui-ci dessous ne plantera pas le script. On vérifie d'abord que StringRegExp n'a pas renvoyé d'erreur. S'il n'y a pas eu d'erreur, $aRet est bien de type array donc on peut afficher la 1ère case sans risque.

Code : Tout sélectionner

$aRet = StringRegExp("aaa", "2(\d{6})", 1)
If Not @error Then ConsoleWrite($aRet[0] & @CRLF)
De petits détails peuvent faire toute la différence. — Quand la boule de neige commence à rouler… poussez-la. (Columbo)
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Expressions régulières : Comparer et remplacer

#11

Message par mikell »

orax a écrit :On pourrait même ajouter $ en plus de ^ => ^2\d{12}$
Dans ce cas on impose comme condition que la chaîne comprenne exactement 13 caractères (ce qui n'est pas forcément le test recherché, si on ne veut tester que le début de la chaîne sans tenir compte de sa longueur)
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Pyrithe
Niveau 1
Niveau 1
Messages : 12
Enregistré le : lun. 03 oct. 2011 11:35
Status : Hors ligne

Re: [..] Expressions régulières : Comparer et remplacer

#12

Message par Pyrithe »

Bon j'ai pas trop déconné, puisque lors de mes tests, j'ai bien ajouté le ^ en pattern pour exprimer le premier caractère, et le $ de fin de chaîne permettant de limiter mon nombre de caractères.
Puisque pour le moment je ne suis pas capable de déterminer tous les cas de figures, ca me permet de ne pas avoir de soucis.

En tous cas un immense merci, j'ai pu atteindre mon but, et surtout apprendre un certain nombre de choses!!

J'améliore dès que j'ai un moment le truc, j'y ai ajouté une GUI, une fonction de copie du code généré dans le presse-papier, et je vais ajouter une fonction de lecture/écriture dans un fichier excel (je ne me suis pas encore penché dessus).

Ce matin j'ai essayé quelque chose, sans succès. Si vous maîtrisez les regexp vous pourrez peut-être m'aider.
Je voulais récupérer la saisie du code dans mon input

Code : Tout sélectionner

$InputCB = GUICtrlCreateInput("", 30, 110, 200, 21)
Ca marche parfaitement avec GUICtrlRead
Mais je voulais, avant de tester la correspondance avec les pattern, supprimer tout caractère non numérique de la chaine.

Deux raisons à ca :
1- L'utilisateur pourrait involontairement taper un caractère supplémentaire au clavier
2- Le scanner est configuré pour être utilisé avec un logiciel, et ajoute systématiquement un caractère de début de code et fin de code (qui sont des crochets [ ] )

Je n'ai pas trouvé comment le faire...
Avatar du membre
orax
Modérateur
Modérateur
Messages : 1479
Enregistré le : lun. 23 mars 2009 04:50
Localisation : ::1
Status : Hors ligne

Re: [..] Expressions régulières : Comparer et remplacer

#13

Message par orax »

Code : Tout sélectionner

StringRegExpReplace("123abc45a6", "\D+", "")
Et pour éviter que l'utilisateur tape autre chose que des nombres :

Code : Tout sélectionner

#include <EditConstants.au3>
$InputCB = GUICtrlCreateInput("", 30, 110, 200, 21, $ES_NUMBER)
De petits détails peuvent faire toute la différence. — Quand la boule de neige commence à rouler… poussez-la. (Columbo)
Répondre