Bonsoir
question bête, si ce qui compte ce sont les caractères entre 10 et AR, le reste (85, 15, 36, 29) a-t-il vraiment de l'importance ?
Par exemple, existe-t-il des séquences contenant 10 et AR mais sans 85, 15, 36, 29 et qui du coup ne serait pas à capturer ?
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
(?<=10).{1,20}(?=AR)
Un exemple ici https://regex101.com/r/Q8ToAf/1
La dernière ligne n'est pas capturée, car il y a 21 caractères entre 10 et AR
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Le problème à découper la séquence par partie est le risque de collision.
Par exemple, s'il y a 11 dans les caractères qui suivent le 01, la capture commencera là. Cf cet exemple, les 4 premières lignes sont celles de ton code et la dernière est la précédente que j'ai modifiée pour illustrer.
À mon sens, il faut essayer de trouver un(des) pattern qui t'immunise de ce risque.
Je n'aurais pas trop le temps de me pencher sérieusement sur la question aujourd'hui. J'y regarderai ce week-end.
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Ce qui ne marche pas en vba, c'est (au moins) les groupes nommés.
Ça on peut s'en passer, il faut juste savoir le numéro du groupe qu'on cherche.
Il faut voir si les options sont acceptées.
Je n'ai pas fait de tests approfondis. Mais j'aurais un peu de temps ce matin.
Le risque avec les "ou" comme tu l'as fait c'est de faire matcher une séquence avec des doublons, mais plus haut tu indiques qu'il ne peut pas y en avoir. Donc ça ne serait pas un problème. Il faut juste en être conscient. C'est d'ailleurs sur une combinaison de ou que je voulais plancher.
Et à priori, comme tu as inclus la balise 01 dans le ou, ça doit pouvoir matcher si elle n'est pas en première position.
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Ha et t'as mis des "anti" préfixes, ça non plus ça ne doit pas marcher en VBA.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionAu temps pour moi, j'avais pas déclaré les variable d'itération des for
Option Explicit Sub TestNeriXs() Dim pattern01, pattern11, pattern17, pattern10, pattern21, pattern, code, capture, balise, resultat As String Dim regex, matches, Match As Object Dim codes As Variant Dim i As Integer codes = Array("0100883873867792112209271723092710220927GS21PC23713163", "01008838738677921723092710220927GS21PC23713163GS11220927", "0100883873867792112209271723092710220927GS21PC23713163", "01034009301383801726013110DB20323GS2195918770106437", "01034009301884081726060010ABS3514", "01034009346722482110045423841916GS10X09897AGS17260430") Set regex = New RegExp pattern01 = "^(01.{14})" pattern11 = "(11\d{6})" pattern17 = "(17\d{6})" pattern10 = "(10.{1,20}?)(?:GS|$)" pattern21 = "(21.{1,20}?)(?:GS|$)" pattern = pattern01 + "(?:" + pattern11 + "|" + pattern17 + "|" + pattern10 + "|" + pattern21 + ")+$" regex.pattern = pattern For Each code In codes If (regex.Test(code)) Then Set matches = regex.Execute(code) For Each Match In matches For i = 0 To Match.SubMatches.Count - 1 capture = Match.SubMatches.Item(i) balise = Left(capture, 2) Select Case balise Case "01" resultat = balise + ": " + Right(capture, 14) + ", " Case "11", "17" resultat = resultat + balise + ": " + Right(capture, 6) + ", " Case "10", "21" resultat = resultat + balise + ": " + Right(capture, Len(capture) - 2) + ", " End Select Next Debug.Print code Debug.Print resultat Next End If Next End Sub
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Alors, le pourquoi du comment.
D'abord, je t'ai posé plein de question pour cerner le besoin, parce que forcément, je n'ai pas toute ton expérience sur le sujet et pour poser des hypothèses réalistes, il me fallait des infos.
Donc forcément, c'était un peu long.
Ensuite, regex VBA => exit les préfixes/suffixes (qu'ils soient obligés ou interdits) et les groupes nommés.
Pour les groupes, il faut faire en sorte de savoir de quelles balises on parle, et pour ça mon axiome de départ a été : la balise fait partie de la capture et on trie ensuite grâce aux 2 premiers caractères.
Pour les pré/suffixes, il faut trouver d'autres syntaxes.
Mes hypothèses ont été
Balise | Position | Valeur |
01 | début | 14 caractères |
11 | n'importe où | 6 chiffres |
17 | n'importe où | 6 chiffres |
10 | n'importe où | 1 à 20 caractères + GS ou fin de séquence |
21 | n'importe où | 1 à 20 caractères + GS ou fin de séquence |
À partir de là, j'ai tenté un premier jeu de patterns, qui s'est révélé bon pour les 3 premiers.
Pattern unitaire | Signification |
^(01.{14}) | Début de séquence, groupe qui capture la balise et 14 caractères |
(11\d{6}) | Groupe qui capture la balise et 6 chiffres |
(17\d{6}) |
Mais ça ne marchait pas pour les balises 10 et 21.
Sur tes codes barres de test, il y en avait un où il y avait un 10 et un 21 à la suite (ou inversement) dont qui totalisait moins de 20 caractères. Du coup, il n'y avait qu'une capture qui s'est arrêtée au 2eme GS. Du coup, il fallait ajouter une contrainte pour que la capture soit la plus courte possible (en ajoutant ? après {1,20} )
Pattern unitaire | Signification |
^(01.{14}) | Début de séquence, groupe qui capture la balise et 14 caractères |
(11\d{6}) | Groupe qui capture la balise et 6 chiffres |
(17\d{6}) | |
(10.{1,20}?)(?:GS|$) | Groupe qui capture la balise, puis de 1 à 20 caractères, mais le plus court possible, puis GS ou fin de séquence qui ne sont pas dans le groupe |
(21.{1,20}?)(?:GS|$) |
Ensuite, il fallait mettre tout ça dans une seule regex, avec des ou comme tu l'avais présenti, sauf la balise 01 qui est toujours présent et au début de la séquence, donc ne doit pas être dans le "ou".
Ensuite ce qui est dans le "ou" arrive plusieurs fois, mais on ne sait pas dire combien (donc un + comme quantificateur).
Enfin la capture va jusqu'à la fin de la séquence.
Si on appelle pXX chaque pattern unitaire ça donne
p01(?:p11|p17|p10|p21)+$
Après avoir validé ça sur regex101, je l'ai transposé en VBA.
J'ai gardé l'idée des patterns unitaires pour plus de lisibilité et surtout c'est plus facile de retoucher un pattern unitaire si besoin qu'une grande regex.
Ce qui a donné ce code, que j'ai commenté
Sub TestNeriXs() Dim pattern01, pattern11, pattern17, pattern10, pattern21, pattern, code, capture, balise, resultat As String Dim regex, matches, Match As Object Dim codes As Variant Dim i As Integer 'mise de plusieurs codes de test dans un tableau codes = Array("0100883873867792112209271723092710220927GS21PC23713163", "01008838738677921723092710220927GS21PC23713163GS11220927", "0100883873867792112209271723092710220927GS21PC23713163", "01034009301383801726013110DB20323GS2195918770106437", "01034009301884081726060010ABS3514", "01034009346722482110045423841916GS10X09897AGS17260430") Set regex = New RegExp 'écriture des patterns unitaires pattern01 = "^(01.{14})" pattern11 = "(11\d{6})" pattern17 = "(17\d{6})" pattern10 = "(10.{1,20}?)(?:GS|$)" pattern21 = "(21.{1,20}?)(?:GS|$)" 'fusion du pattern complet pattern = pattern01 + "(?:" + pattern11 + "|" + pattern17 + "|" + pattern10 + "|" + pattern21 + ")+$" regex.pattern = pattern 'test de chaque code du tableau For Each code In codes 'on vérifie d'abord que la regex matche If (regex.Test(code)) Then 'si oui, on recoupère les datas 'comme je ne savais pas si tu récupères les codes un à un ou en lot (dans un fichier par exemple), 'je suis parti du principe qu'il pouvait y avoir plusieurs matches Set matches = regex.Execute(code) For Each Match In matches 'pour chaque match, on récupère les groupes For i = 0 To Match.SubMatches.Count - 1 capture = Match.SubMatches.Item(i) 'on extrait la balise pour affecter le résultat comme il faut balise = Left(capture, 2) 'j'ai choisi un select case, car ça se prête bien à la situation Select Case balise Case "01" resultat = balise + ": " + Right(capture, 14) + ", " Case "11", "17" resultat = resultat + balise + ": " + Right(capture, 6) + ", " Case "10", "21" resultat = resultat + balise + ": " + Right(capture, Len(capture) - 2) + ", " End Select Next 'on imprime le résultat dans la console Debug.Print code Debug.Print resultat Next End If Next End Sub
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Que l'on peut modifier par exemple comme ça
Option Explicit Sub TestNeriXs() Dim pattern01, pattern11, pattern17, pattern10, pattern21, pattern, code, capture, balise, resultat, gtin, dateProd, dateExpi, numLot, numSerie As String Dim regex, matches, Match As Object Dim codes As Variant Dim i As Integer 'mise de plusieurs codes de test dans un tableau codes = Array("0100883873867792112209271723092710220927GS21PC23713163", "01008838738677921723092710220927GS21PC23713163GS11220927", "0100883873867792112209271723092710220927GS21PC23713163", "01034009301383801726013110DB20323GS2195918770106437", "01034009301884081726060010ABS3514", "01034009346722482110045423841916GS10X09897AGS17260430") Set regex = New RegExp 'écriture des patterns unitaires pattern01 = "^(01.{14})" pattern11 = "(11\d{6})" pattern17 = "(17\d{6})" pattern10 = "(10.{1,20}?)(?:GS|$)" pattern21 = "(21.{1,20}?)(?:GS|$)" 'fusion du pattern complet pattern = pattern01 + "(?:" + pattern11 + "|" + pattern17 + "|" + pattern10 + "|" + pattern21 + ")+$" regex.pattern = pattern 'test de chaque code du tableau For Each code In codes 'on vérifie d'abord que la regex matche If (regex.Test(code)) Then 'si oui, on recoupère les datas 'comme je ne savais pas si tu récupères les codes un à un ou en lot (dans un fichier par exemple), 'je suis parti du principe qu'il pouvait y avoir plusieurs matches Set matches = regex.Execute(code) For Each Match In matches 'pour chaque match, on récupère les groupes For i = 0 To Match.SubMatches.Count - 1 capture = Match.SubMatches.Item(i) 'on extrait la balise pour affecter le résultat comme il faut balise = Left(capture, 2) 'j'ai choisi un select case, car ça se prête bien à la situation Select Case balise Case "01" gtin = Right(capture, 14) resultat = "(01)" + gtin Case "11" dateProd = Right(capture, 6) resultat = resultat + "(11)" + dateProd Case "17" dateExpi = Right(capture, 6) resultat = resultat + "(17)" + dateExpi Case "10" numLot = Right(capture, Len(capture) - 2) resultat = resultat + "(10)" + numLot Case "21" numSerie = Right(capture, Len(capture) - 2) resultat = resultat + "(21)" + numSerie End Select Next 'on imprime le résultat dans la console Debug.Print resultat Debug.Print "(01) GTIN de l’article: " + gtin Debug.Print "(11) Date de production: " + dateProd Debug.Print "(17) Date d'expiration : " + dateExpi Debug.Print "(10) Numéro de lot: " + numLot Debug.Print "(21) Numéro de série: " + numSerie Next End If Next End Sub
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Le pattern01 part du principe que le code barre commence par la balise 01.
Si une balise FNC1 est présente, ça n'est plus le cas et donc ça ne matche pas.
Option 1 enlever le "^" au début du pattern et la capture commencera au premier 01. Mais si tu as un code en entrée qui ne correspond pas aux autres balises, ça pourrait mettre le bazar.
Option 2, modifier le pattern01 pour qu'il accepte ces balises en option, pas testé, mais à priori ça devrait ressembler à
"^(?:](?:C1|e0|d2|Q3|J1))?(01.{14})"
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Vu ton autre question, j'ai utilisé une classe.
Il faut ajouter un module de classe, le renommer UnCode et copier coller ça dedans
'Champs utiles Public Capture As String Public Balise As String Public LeCode As String Public Position As Integer 'Initialise l'instance de l'objet UnCode Public Sub Init(LaCapture As String, LaPosition As Integer) Capture = Replace(Replace(LaCapture, "(", ""), ")", "") Position = LaPosition Balise = Left(Capture, 2) LeCode = Right(Capture, Len(Capture) - 2) End Sub 'Méthode qui retourne un texte sous la forme "(Balise)LeCode" Public Function Texte() As String Texte = "(" & Balise & ")" & LeCode End Function 'Méthode qui retourne un texte sous la forme "(Balise) Description : LeCode" Public Function Description() As String Dim madescription As String Select Case Balise Case "01" madescription = "(01) GTIN de l’article: " Case "11" madescription = "(11) Date de production: " Case "17" madescription = "(17) Date d'expiration : " Case "10" madescription = "(10) Numéro de lot: " Case "21" madescription = "(21) Numéro de série: " End Select Description = madescription + LeCode End Function
Ensuite, il faut modifier la lecture comme ça
Function TestNeriXs(code As String) As String Dim pattern01, pattern11, pattern17, pattern10, pattern21, pattern, ligne1, ligne2 As String Dim regex, matches, Match As Object Dim i, Position As Integer Dim resultats As Dictionary Dim unCode As unCode Set regex = New RegExp 'écriture des patterns unitaires pattern01 = "^(?:](?:C1|e0|d2|Q3|J1))?(\(?01\)?.{14})(?:GS|\x1d)?" pattern11 = "(\(?11\)?\d{6})(?:GS|\x1d)?" pattern17 = "(\(?17\)?\d{6})(?:GS|\x1d)?" pattern10 = "(\(?10\)?.{1,20}?)(?:GS|$|\x1d|\()" pattern21 = "(\(?21\)?.{1,20}?)(?:GS|$|\x1d|\()" 'fusion du pattern complet pattern = pattern01 + "(?:" + pattern11 + "|" + pattern17 + "|" + pattern10 + "|" + pattern21 + ")+$" regex.pattern = pattern 'valeur par défaut si la regex ne matche pas ligne1 = "Code incorrect" 'on vérifie d'abord que la regex matche If (regex.test(code)) Then 'si oui, on recoupère les datas 'comme je ne savais pas si tu récupères les codes un à un ou en lot (dans un fichier par exemple), 'je suis parti du principe qu'il pouvait y avoir plusieurs matches Set matches = regex.Execute(code) For Each Match In matches ligne1 = "" ligne2 = "" Set resultats = New Dictionary Set unCode = New unCode unCode.Init Match.SubMatches.item(0), 1 resultats.Add "01", unCode 'on ajoute les submatches 1 à n For i = 1 To Match.SubMatches.Count - 1 Position = InStr(code, Match.SubMatches.item(i)) If Position > 1 Then 'les groupes qui ne macthent rien sont vides et ça donne une position à 1 Set unCode = New unCode unCode.Init Match.SubMatches.item(i), Position resultats.Add Format(Position, "00"), unCode End If Next 'on repart de la position 1 i = 1 Do Set unCode = resultats.item(Format(i, "00")) 'la ligne1 est la reconstitution du code avec les parenthèses, la ligne2 les descriptions ligne1 = ligne1 + unCode.Texte() ligne2 = ligne2 + vbCrLf + unCode.Description() i = i + Len(unCode.Capture) 'on passe à la position suivante à partir de laquel il faut chercher une clé 'on vérifie que la clésuivante existe Do While Not resultats.Exists(Format(i, "00")) And i < Len(code) i = i + 1 'il faut incrémenter pour passer les GS et les ( qui ont été ignorés Loop Loop While i < Len(code) 'quand on a atteint la taille du code (pour GS...), c'est qu'on a fini Next End If TestNeriXs = ligne1 + ligne2 End Function
Avec ce code de test
Sub test() Dim codes, code As Variant codes = Array("0107332414124359210000107668GS11210208", "(01)00843997013703(11)210601(17)230601(21)3000105704", "(01)00843997013703(11)210601(17)230601(10)54gp75P(21)3000105704", "(01)00843997013703(11)210601(10)54gp75P(17)230601(21)3000105704") For Each code In codes Debug.Print (code + " => ") Debug.Print (TestNeriXs(CStr(code))) Debug.Print ("") Next End Sub
J'obtiens
0107332414124359210000107668GS11210208 => (01)07332414124359(21)0000107668(11)210208 (01) GTIN de l’article: 07332414124359 (21) Numéro de série: 0000107668 (11) Date de production: 210208 (01)00843997013703(11)210601(17)230601(21)3000105704 => (01)00843997013703(11)210601(17)230601(21)3000105704 (01) GTIN de l’article: 00843997013703 (11) Date de production: 210601 (17) Date d'expiration : 230601 (21) Numéro de série: 3000105704 (01)00843997013703(11)210601(17)230601(10)54gp75P(21)3000105704 => (01)00843997013703(11)210601(17)230601(10)54gp75P(21)3000105704 (01) GTIN de l’article: 00843997013703 (11) Date de production: 210601 (17) Date d'expiration : 230601 (10) Numéro de lot: 54gp75P (21) Numéro de série: 3000105704 (01)00843997013703(11)210601(10)54gp75P(17)230601(21)3000105704 => (01)00843997013703(11)210601(10)54gp75P(17)230601(21)3000105704 (01) GTIN de l’article: 00843997013703 (11) Date de production: 210601 (10) Numéro de lot: 54gp75P (17) Date d'expiration : 230601 (21) Numéro de série: 3000105704
Je crois que pour les patterns regroupés, j'y suis.
La classe modifiée comme suit
'Champs utiles Public AI As String Public Code As String 'Initialise l'instance de l'objet UnCode Public Sub Init(LaBalise As String, LeCode As String) AI = LaBalise Code = LeCode End Sub 'Méthode qui retourne un texte sous la forme "(Balise)LeCode" Public Function Texte() As String Texte = "(" & AI & ")" & Code End Function 'Méthode qui retourne un texte sous la forme "(Balise) Description : LeCode" Public Function Description() As String Dim madescription As String Select Case AI Case "01" madescription = "(01) GTIN de l’article: " Case "11" madescription = "(11) Date de production: " Case "17" madescription = "(17) Date d'expiration : " Case "10" madescription = "(10) Numéro de lot: " Case "21" madescription = "(21) Numéro de série: " Case "91" madescription = "(91) InfosInternes: " End Select Description = madescription + Code End Function
Le code de déchiffrement comme suit
Function TestNeriXs4(Code As String) As String Dim fnc1, gs, caracteresOK, pattern, ligne1, ligne2 As String Dim regex, Match As Object Dim i As Integer Dim resultats As Collection Dim unCode As unCode Dim patterns As Variant Dim boucleOut As Boolean Set regex = New RegExp 'écriture des patterns unitaires gs = "(\x1d|\()?" 'quand c'est peut-être fnc1 = "(\x1d|$|\()" 'quand c'est obligé caracteresOK = "[\x21-\x22\x25-\x3F\x41-\x5A\x5F\x61-\x7A]" 'on met les patterns unitaires dans un tableau patterns = Array("(?:](?:C1|e0|d2|Q3|J1))?\(?(01)\)?(" + caracteresOK + "{14})" + gs, _ "\(?(1[123567])\)?(\d{6})" + gs, _ "\(?(10)\)?(" + caracteresOK + "{1,20}?)" + fnc1, _ "\(?(21)\)?(" + caracteresOK + "{1,20}?)" + fnc1 _ ) '"(\(?9[1-9]\)?" + caracteresOK + "{0,90})" + fnc1 _ 'valeur par défaut si la regex ne matche pas ligne1 = "Code incorrect" ligne2 = "" Set resultats = New Collection Do boucleOut = False For Each pattern In patterns 'on teste chaque pattern pour le début du code regex.pattern = "^" + pattern If (regex.Test(Code)) Then boucleOut = True ligne1 = "" 'si ça marche, on extrait la partie Set Match = regex.Execute(Code)(0) Set unCode = New unCode unCode.Init Match.SubMatches(0), Match.SubMatches(1) resultats.Add unCode 'on enlève ce qu'on vient de traiter Code = Replace(Code, Match.Value, "") 'et on recommence Exit For End If Next Loop While Len(Code) > 0 And boucleOut 'si boucleOut vaut false c'est qu'on vient de faire un tour complet et qu'on est sur un cas imprévu If boucleOut = False Then ligne1 = "Erreur data imprévue" + vbCrLf End If For i = 1 To resultats.Count Set unCode = resultats(i) ligne1 = ligne1 + unCode.Texte ligne2 = ligne2 + vbCrLf + unCode.Description Next TestNeriXs4 = ligne1 + ligne2 End Function
Pour l'instant, exprès j'ai exclu 9X
Et le code de test
Sub Test() Dim codes() As Variant Dim Code As Variant 'mise de plusieurs codes de test dans un tableau codes = Array("(01)00843997013703(11)210601(17)230601(21)3000105704", "010088483808258821DE7840AL79" + Chr(29) + "91867031", "0107332414124359210000107668" + Chr(29) + "11210208", "(01)00843997013703(11)210601(17)230601(10)54gp75P(21)3000105704", "(01)00843997013703(11)210601(10)54gp75P(17)230601(21)3000105704", "]C10100883873867792112207071723070710220707" + Chr(29) + "21PC22412085") For Each Code In codes Debug.Print (Code) Debug.Print (TestNeriXs4(CStr(Code))) Debug.Print ("") Next End Sub
Dans lequel, d'une part GS n'apparait plus en texte mais \x21, et d'autre part, il y a un AI 91.
Je m'explique, je ne teste plus le code entier, mais juste le début pour un pattern, puis le suivant, puis le suivant etc..
Quand ça matche, je supprime la capture du code jusqu'à la fin.
Le risque, c'est de tomber sur un cas imprévu et de boucler à l'infini, j'ai donc mis un garde-fou et je le teste avec un AI 91.
Maintenant, on peut se pencher sur les 2 problèmes suivants
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Dans ton tableau #72 tu as marqué dans le groupe 13 que fnc1 est requis.
Hors, je regarde au hasard, cette page https://www.gs1.org/standards/barcodes/application-identifiers à l'onglet 13, l'AI 3630 et FNC1 n'est pas requis.
Je ne sais pas si c'est la seule erreur, mais il va falloir revoir ce tableau.
Bonsoir,
en effet, il faut être très vigilant avec les parenthèses (la preuve....)
En regex, elles délimitent un groupe, ce groupe peut être
ab(.+)ba, va créer une capture de tout ce qu'il y a entre ab et ba.
ab(?:12|21)bamatchera ab12ba ou ab21ba et "SubMatchera" 12 ou 21
J'ai basé le traitement actuel sur le fait qu'une SubMatch sera l'AI et l'autre la description.
Mais les AI peuvent être elles-mêmes entourés de parenthèses.
Il faut donc encadrer le groupe de capture de l'AI de parenthèses échapées et optionnelle.
Ce qui pour l'AI 1234 donne
\(?(1234)\)?
Teste tes patterns sur regex101, tu vois le résultat en direct, tu as le détail des groupes de captures
Je te conseille de commencer par valider les fusions d'AI, puis de les entourer d'un groupe de capture et des parenthèses optionnelles.
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Citation:
Je te conseille de commencer par valider les fusions d'AI.
Réponse:
Je ne vois pas trop comment valider ces groupes de fusion avec certitude.
Quels conseils me donnerais-tu pour être le plus juste?
Les paramètre que j'ai appliqué sont:
FNC requis ou pas, Pattern identique.
Tu as bien fait d'insister pour la justesse des groupes !
J'avais oublié un pattern "^X(\d{0,6})$" soit 10 AI qui n'étaient pas dans le bon groupe.
Soit 3950 à 3959.
3 AI dans un mauvais groupe, car requières une balise de fin.
Soit 4326, 7006, 8005.
Nouvelle version : Groupe-Pattern-V3
J'ai séparé Les Ai 01 et 02 comme tu me l'as rappelé "01 et éventuel FNC au début".
Bonjour
tu peux utiliser une Collection
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Url = "https://id.gs1.org/" + primaryKey + keyQualifier If dataAttribute <> "" Then Url = Url + "?" + dataAttribute End If
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
OK, c'est compris.
Je faisais une fixation et m'acharnais à vouloir absolument apporter la modification sur la partie de construction selon les groupes d'AI.
Pourtant mon pattern agissait bien sur l'url final, là c'est la même chose.
Désolé et merci pour la solution finale
Bonsoir,
Effectivement ce qui compte ce sont les caractères entre 10 et AR!
J'essaie de jouer avec (.+?) mais je sèche toujours !
Il y a quelque chose qui m'échappe !
85(\d{14})36(\d{6})10(?<=10).{1,20}(?=AR)29(\d{6})15(PC\d+)$
85339147802789523626847310205970239AR2950793415PC7098624031
Cette instruction
(?<=10)
veut dire que 10 doit être avant la capture mais pas en faire partie.
Du coup, tu ne peux pas la mettre au milieu d'un pattern, idem pour (?=AR) qui signifie après la capture.
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Comment pourrais-je modifier mon code VBA pour être compatible?
Function ExtractInfoGS1_128(Chaine As String, numInfo As Integer) As String ' Création de l'objet RegExp ExtractInfoGS1_128 = "Erreur" Set regEx = CreateObject("VBScript.RegExp") regEx.Global = True regEx.IgnoreCase = True regEx.Pattern = "85(\d{14})36(\d{6})10((?<=10).{1,20}(?=AR))29(\d{6})15(PC\d+)$" 'Expression régulière If matches.Count = 1 Then Debug.Print "Identifiant de l'appareil : ", matches(0).submatches(0) Debug.Print "Date de fabrication : ", matches(0).submatches(1) Debug.Print "Date d'expiration : ", matches(0).submatches(2) Debug.Print "Numéro de lot/lot : ", matches(0).submatches(3) Debug.Print "Numéro de série : ", matches(0).submatches(4) ExtractInfoGS1_128 = matches(0).submatches(numInfo - 1) End If End Function Sub TestRegex() Debug.Print ExtractInfoGS1_128("85339147802789523626847310205970239AR2950793415PC22412085", 4) End Sub
Ha c'est du VBA
le moteur de regex de VBA est ancien, je ne sais pas s'il prend en compte les prefixes et les suffixes.
Mais de toute façon, ils ne peuvent pas être au milieu.
D'autre part, quand je t'ai demandé si les 85, 36 et consorts avaient de l'importance tu m'as répondu non, donc pourquoi les remettre alors la regex qui ne s'en préoccupe pas est simple?
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Bonjour @Whismeril,
Effectivement le moteur de RegEx de VBA ne prend en compte les préfixes et les suffixes!
Désolé, quand j'ai répondu que les 85, 36 et consorts n'avaient pas d'importance, j'ai pensé que cela pourrait être géré séparément.
Dans le genre:
Function ExtractInfo(txt As String, matrice) As String With CreateObject("VBScript.RegExp") .Pattern = matrice .IgnoreCase = True ExtractInfo = .Execute(txt)(0) End With End Function Sub test10() Dim Chaine As String Chaine = "85339147802789523626847310205970239AR2950793415PC7098624031" Extract85 = ExtractInfo(Chaine, "(?<=85).(\d{14})") Extract36 = ExtractInfo(Chaine, "(?<=36).(\d{6})") Extract10 = ExtractInfo(Chaine, "(?<=10).{1,20}(?=AR)") Extract29 = ExtractInfo(Chaine, "(?<=29).(\d{6})") Extract15 = ExtractInfo(Chaine, "(?<=15).{1,20}$") MsgBox Extract85 & vbCrLf & Extract36 & vbCrLf & Extract10 & vbCrLf & Extract29 & vbCrLf & Extract15 End Sub
Mais vu le moteur de RegEx de VBA pose problème !
Une autre approche est-elle possible ?