[REGEX] Recherche Patten de capture, un défi ?

Résolu
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 - 11 oct. 2023 à 20:43
Whismeril Messages postés 19039 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 7 mai 2024 - 27 févr. 2024 à 23:34

Bonjour à tous,

J'essaie vainement de créer un Patten de capture.

Voici la chaine concernée:

85339147802789523626847310205970239AR2950793415PC7098624031

De cette chaine, j'aimerais capturer les caractères qui sont après 10 jusqu'à AR.

Soit : 205970239

Les contraintes:

Après 85 il y a toujours 14 caractères variable.

Après 36 il y a toujours 6 caractères variable.

Le nombre de caractères entre 10 et AR et compris entre 1 et 20 caractères variable.

Après 29 il y a toujours 6 caractères variable.

Après 15 le nombre de caractères et compris entre 1 et 20 caractères variable.

85, 36, le couple 10 et AR, 29 et 15 serons toujours présent.

85 est toujours en début de chaine.

Les positions de 36, du couple 10 et AR, 29 et 15 peuvent changer

Dans ma chaine d'exemple nous avons:

85, 36, le couple 10 et AR, 29 et 15

Ça pourrait être:

85, 29, le couple 10 et AR, 15 et 36

Ou encore:

85, le couple 10 et AR, 15, 36, 29

J'espère être assez claire et que vous pourrez m'aider ?

142 réponses

NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
18 oct. 2023 à 14:42

Pour incrémenter les TextBox(s) de mon UserForm j'ai modifié le code de cette façon:

Option Explicit

Function TestNeriXs(code As String) As String
Dim pattern01, pattern11, pattern17, pattern10, pattern21, pattern, capture, balise, resultat, gtin, dateProd, dateExpi, numLot, numSerie As String
Dim regex, matches, Match As Object
Dim i As Integer

Set regex = New RegExp

'écriture des patterns unitaires
'Commençant avec la balise 01
'pattern01 = "^(01.{14})"
'Commençant éventuellement par un FNC1 (]C1, ]e0, ]d2, ]Q3, ]J1).
pattern01 = "^(?:](?:C1|e0|d2|Q3|J1))?(01.{14})"
pattern11 = "(11\d{6})"
pattern17 = "(17\d{6})"
'pattern10 = "(10.{1,20}?)(?:GS|$)"
pattern10 = "(10.{1,20}?)(?:GS|$|\x1d)"
'pattern21 = "(21.{1,20}?)(?:GS|$)"
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
resultat = "Code incorrect"

'on vérifie d'abord que la regex matche
If (regex.test(code)) Then
    'si oui, on recoupère les datas
    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 écrit le résultat complet
        FrmInterface.TxtAllData = resultat
        'Résultat détaillé pour chaque balise.
        FrmInterface.TxtGtinData = gtin
        FrmInterface.TxtProducData = dateProd
        FrmInterface.TxtExpirData = dateExpi
        FrmInterface.TxtLotData = numLot
        FrmInterface.TxtSnData = numSerie
    Next
End If
TestNeriXs = resultat
End Function

Le bouton:

Private Sub BTDecod_Click()

TxtAllData.Value = TestNeriXs(TxtCodeBarres.Value)

End Sub

Pourais-tu valider cette modification?


Comment gérerais-tu le fait qu'une balise n'est pas présente dans le code-barres et afficher " Pas d'information"?

0
Whismeril Messages postés 19039 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 7 mai 2024 656
18 oct. 2023 à 16:37

Puisque tu as écrit cette ligne

        'on écrit le résultat complet
        FrmInterface.TxtAllData = resultat

Pas besoin d'affecter à nouveau TxtAllData dans le bouton.

Attention cependant à la mauvaise pratique d'affecter un texte à une textbox.

Il y a une conversion implicite derrière, l'interprèteur se dit "ha il veut en fait affecter la propriété Value" ce qui est souvent le cas. Mais on pourrait imaginer des cas où ce ne serait pas ce que tu cherches à faire.

Le mieux est de s'astreindre à utiliser la bonne propriété.

Voire, encore mieux, activer Option Strict.

D'autant que cette conversion implicite n'existe pas pour tous les VB et si un jour tu changes c'est mieux d'avoir déjà la bonne pratique.


0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
Modifié le 20 oct. 2023 à 18:16

Bonjour,

J'ai des codes-barres ou il y a une balise GS a chaque fin de balise.

Sauf si dernière.

01 => GS
11 => GS
17 => GS
10 => GS
21 => GS

Exemple:
0100843997013703GS11210601GS213000105704

Je pensais utiliser (?:<GS>|$) à la fin de chaque pattern, mais ça match que pour ce code!
Les autres ne match plus!

Je remets les patterns ici:

pattern01 = "^(?:](?:C1|e0|d2|Q3|J1))?(01.{14})"
pattern11 = "(11\d{6})"
pattern17 = "(17\d{6})"
pattern10 = "(10.{1,20}?)(?:GS|$)"
pattern21 = "(21.{1,20}?)(?:GS|$)"
0
Whismeril Messages postés 19039 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 7 mai 2024 656
20 oct. 2023 à 23:51

Ajouter (?:GS|$) à la fin de chaque pattern, veut dire qu'il faut obligatoirement GS ou fin de ligne. Or ça n'est pas le cas, il peut n'y avoir ni l'un ni l'autre.

A priori, je dirais qu'il faut juste ajouter, "il peut y avoir GS ou pas" => (?:GS)? puisque les seules balises où c'est obligatoirement GS ou fin de ligne c'est 10 et 21 car on ne sait pas à l'avance le nombre de caractères qui suivent.

Sauf si quand il y a GS pour 01, 11 ou 17, le nombre de caractères peut varier.


0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
21 oct. 2023 à 01:29

OK pour GS ou pas => (?:GS)?, ça match.
Merci

Je pensais avoir fait le tour, mais un nouveau cas de figure!

Pas de balises, mais les parenthèses directement dans le code-barres.

En scannant le code-barres j'ai directement:
(01)00843997013703(11)210601(17)230601(21)3000105704

Dans ce cas je dois ignorer la partie RegEx et directement avec LA condition qui va bien alimenter mes TextBox.

Depuis le code actuel, je ne vois trop où et comment gérer LA condition du Code-Barres qui possède déjà les parenthèses.

0
Whismeril Messages postés 19039 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 7 mai 2024 656
21 oct. 2023 à 15:29

Bonjour

en supposant que les GS soit aussi présents quand les balises 10 et 21 sont au milieu (ce qu'on ne peut pas savoir avec ton exemple)

'é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)"

Dans l'absolue, ça matchera avec une seule parenthèse sur les 2. On peut faire en sorte que ça ne soit pas le cas


0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
21 oct. 2023 à 18:51

J'essaie de comprendre pourquoi mais, cher moi le code-barres (l'exemple) avec parenthèses ne match pas.

0
Whismeril Messages postés 19039 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 7 mai 2024 656
21 oct. 2023 à 21:58

Ha parce que j'ai mal fait mon test.

Ça marche sur Regex101, mais pas sur VBA.

Et comme je ne trouve pas pourquoi, voilà une solution qui fonctionne, bien testée.

'é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)"
code = Replace(Replace(code, "(", ""), ")", "")

0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
22 oct. 2023 à 01:16

Test 1
(01)00843997013703(11)210601(17)230601(21)3000105704
Match OK

Test 2
(01)00843997013703(11)210601(17)230601(10)54gp75P(21)3000105704
Patch partiel, Balise 21 non reconnu, donne:
(01)00843997013703(11)210601(17)230601(10)54gp75P213000105704

Test 3
(01)00843997013703(11)210601(10)54gp75P(17)230601(21)3000105704
Ne matche pas du tout!

Test 4
010084399701370311210601213000105704
Match OK

Test 5
01034009353394921726013110371GS2196133094316289
Match OK

Test 6
0100843997013703GS11210601GS213000105704
Match OK

Test 8
]C10100883873867792112209271723092710220927GS21PC23713163
Match OK

Test 9
0100843997013703GS17220601GS11210601GS213000105704
Match OK

Test 10
01034009346722482110045423841916GS10X09897AGS17260430
Match OK

0
Whismeril Messages postés 19039 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 7 mai 2024 656
22 oct. 2023 à 08:34

Ha, donc quand les parenthèses sont présentes, y'a pas les GS.

Donc la solution de les supprimer avant le test regex n'est pas bonne.


0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
22 oct. 2023 à 10:03

Désolé, nous ne nous somme pas compris!

Au poste 41, j'ai écris :
Pas de balises, mais les parenthèses directement dans le code-barres.

En réponse au poste 42, tu écris:
En supposant que les GS soit aussi présents quand les balises 10 et 21 sont au milieu.

Je suis passé à côté de ta réponse.

Donc effectivement, aucune balise GS quand les parenthèses des balises 01, 10, 11, 17 et 21 sont codées directement dans les codes-barres.

0
Whismeril Messages postés 19039 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 7 mai 2024 656
Modifié le 22 oct. 2023 à 11:43

Ha quel idiot, ce n'est pas la regex qui ne marchait pas.

C'est le traitement que j'en faisais ensuite.

Function TestNeriXs(code As String) As String
Dim pattern01, pattern11, pattern17, pattern10, pattern21, pattern, capture, balise, resultat, gtin, dateProd, dateExpi, numLot, numSerie As String
Dim regex, matches, Match As Object
Dim i As Integer

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
resultat = "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
        'pour chaque match, on récupère les groupes
        For i = 0 To Match.SubMatches.Count - 1
            capture = Replace(Replace(Match.SubMatches.Item(i), "(", ""), ")", "")
                      
            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 écrit le résultat complet
        resultat = resultat + vbCrLf + "(01) GTIN de l’article: " + gtin + vbCrLf + "(11) Date de production: " + dateProd + vbCrLf + "(17) Date d'expiration : " + dateExpi + vbCrLf + "(10) Numéro de lot: " + numLot + vbCrLf + "(21) Numéro de série: " + numSerie
    Next
End If
TestNeriXs = resultat
End Function

Avec ce code de test

codes = Array("(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

J'obtiens

(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
(10) Numéro de lot: 
(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(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
 


0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
22 oct. 2023 à 20:08

HA!, très bonne nouvelle, ça match, match et re-match!.

Ce n'était pas si évident que ça! Merci

Au niveau du "décodage" des codes-barres, je pense qu'on doit avoir fait le tour.

Concernant le résultat, penses-tu qu'il soit possible de le mettre dans l'ordre d'origine ?

Exemple:

Code-barres scanné:
0107332414124359210000107668GS11210208

Résultat Excel VBA
(01)07332414124359(11)210208(21)0000107668

Ce qui est affiché sous le code-barres scanné:
(01)07332414124359(21)0000107668(11)210208

Vu que l'ordre semble aléatoire, ce n'est peut-être pas possible?

0
Whismeril Messages postés 19039 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 7 mai 2024 656
23 oct. 2023 à 19:55

Bonsoir

c'est un peu chiant, dans le sens où VBA ne conserve pas la position de chaque capture dans la collection SubMatches.

J'ai donc utilisé un Dictionary (il faut ajouter Microsoft scripting dans les références) dont la clé est la position, convertie en string (la clé ne peut pas être un entier).

Ensuite, par incrément, je cherche la clé suivante.

Function TestNeriXs(code As String) As String
Dim pattern01, pattern11, pattern17, pattern10, pattern21, pattern, capture, balise, resultat, gtin, dateProd, dateExpi, numLot, numSerie As String
Dim regex, matches, Match, item As Object
Dim i, position As Integer
Dim mesItems As Dictionary

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
resultat = "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
        
        'Pour chaque match, on crée un dictionnaire dont la clé est la position dans le code initial et la valeur la captue, sans les GS et les (
        Set mesItems = New Dictionary
        
        'la première valeur est toujours 01
        mesItems.Add "01", Match.SubMatches.item(0)

        '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
                mesItems.Add Format(position, "00"), Match.SubMatches.item(i)
            End If
        Next
        
        'on repart de la position 1
        i = 1
        Do
            'on vérifie que la clé existe
            Do While Not mesItems.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
            
            capture = mesItems.item(Format(i, "00"))
            capture = Replace(Replace(capture, "(", ""), ")", "")
            
            i = i + Len(capture) 'on passe à la position suivante à partir de laquel il faut chercher une clé
            
            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
        Loop While i < Len(code) 'quand on a atteint la taille du code (pour GS...), c'est qu'on a fini
        
        'on écrit le résultat complet
        resultat = resultat + vbCrLf + "(01) GTIN de l’article: " + gtin + vbCrLf + "(11) Date de production: " + dateProd + vbCrLf + "(17) Date d'expiration : " + dateExpi + vbCrLf + "(10) Numéro de lot: " + numLot + vbCrLf + "(21) Numéro de série: " + numSerie
    Next
End If
TestNeriXs = resultat
End Function

0
Whismeril Messages postés 19039 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 7 mai 2024 656
23 oct. 2023 à 19:56

J'aurais pu aussi écrire une classe avec comme propriété la position, tout stocker dans une Collection et ensuite la trier par la position.

0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
24 oct. 2023 à 20:57

Ça fonctionne très bien et en plus j'apprends, merci

Le fait de gérer les patterns individuellement me facilite grandement la tâches pour la finalisation du projet.

Je fais face à une problématique et ne suis pas sûr qu'il y ai une solution!

Le plus souvent les codes-barres utilisent des balises de 2 caractères.
Dans quelques cas, des balises de 3 ou 4 caractères sont utilisés.

J'ai trouvé la liste complète des " Application Identifiers (AI)" que nous avons appelé balises.
https://www.gs1.org/standards/barcodes/application-identifiers

La taille de ces AI est connue, sauf pour ceux variables, c'est ce qui me fait peur!

Voix tu une possibilité de gérer cette nouvelle difficulté?

0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
24 oct. 2023 à 21:11


Information qui me redonne un peu d'espoirs:

FNC1 requit = notre balise GS

Et le pattern de chaque AI (balise)

Sur la même page:

https://www.gs1.org/standards/barcodes/application-identifiers

En haut a droite, changer "Basic view" pour "Advanced view".

0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1 > NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024
24 oct. 2023 à 21:40

Complément d'explication en fin de cette page:

https://docs.esko.com/docs/en-us/deskpack-advanced/14.1/userguide/home.html?q=en-us%2Fcommon%2Fbar%2Fconcept%2Fco_bar_gs1applicationidentifiers.html

Pour les patterns, si j'ai bien compris:

Les balises (AI) exclu:
[\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]

Nous on est OK , GS = \x1D

0
Whismeril Messages postés 19039 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 7 mai 2024 656
25 oct. 2023 à 08:14

OK.

mais selon ta première page, il y a plus de 500 cas à traiter.

Une seule regex n'y arrivera pas. C'est très puissant mais ça a ses limites.

En plus les regex présentées considèrent que le code est déjà découpé, puisque chacune teste le texte entier.

Est ce que tu tombes souvent sur des cas qui sortent de ce qu'on a déjà fait?

Si oui est avec quelques balises identiques ou totalement aléatoires dans les 500 et quelques ?


0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
Modifié le 26 oct. 2023 à 00:59

Pour répondre aux questions:

Est-ce que tu tombes souvent sur des cas qui sortent de ce qu'on a déjà fait?

Ce n'était pas le cas jusqu’à peu, j'exploitais seulement les balises "AI" 01, 10, 11, 17 et 21, soit EAN-128.
Une nouvelle directive du début du mois, concernant ma GMAO m'impose d'utiliser les codes UDI "Identifiant unique des dispositifs (IUD)" le GS1-128.

Si oui est avec quelques balises identiques ou totalement aléatoires dans les 500 et quelques ?

Depuis la Fin de semaine dernière ou j'ai commencé à scanner ces Codes-barres UDI, j'ai rencontré en plus des balises "AI" habituel les balises suivantes:
8013, 421, 241, 253, 90, 91, 37, 24, 42

J'ai aucun doute que d'autres vont arriver vu le nombre de prestataires!

Le problème est que si une des 519 balises est dans un de mes codes-barres je ne pourrais récupérer aucune info "Code Incorrect".

L'avantage de toutes les générer, même avec  nom bidon, le jour ou une d'elles est nécessaire elles sont là!

Peut-être une idée:

En supposant qu'on puisse faire prendre en charge plusieurs balises sur un Pattern!

Exemple avec balises fictives:
3 balises: 54, 78, 103

En reprenant le Pattern 17 qu'on utilise déjà + les 3 balises et le OU (|):

"(\(?17\)?\d{6}) | (\(?54\)?\d{6}) | (\(?78\)?\d{6}) | (\(?103\)?\d{6})(?:GS|\x1d)?"

Ça semble fonctionner, mais il a peut-être plus simple.

Dans ce sens, j'ai pu faire 54 groupes de balises qui utilisent le même Pattern:

Soit un Pattern par groupe.

La convention suivante est appliquée :
 
N = chiffre numérique
X = tout caractère
N3 = 3 chiffres, longueur fixe
N..3 = jusqu'à 3 chiffres numériques
X..3 = jusqu'à 3 caractères

Idem pour 2 et 4

Ou X = balises multiples.

Format => Nombre d'utilisation => Balise(s) concernée(s) => Balise de fin requise "GS" => Pattern

1)    N2+N18 => 1 => 00 => Non => ^0(\d{18})$

2)    N2+N14 => 2 => 01, 02 => Non => ^X(\d{14})$

3)    N2+X..20 => 3 => 10, 21, 22 => Oui => ^X([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,20})$

4)    N2+N6 => 6 => 11, 12, 13, 15, 16, 17 => Non => ^X(\d{6})$

5)    N2+N2 => 1 => 20 => Non => ^20(\d{2})$

6)    N3+X..28 => 1 => 235 => Oui => ^235([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,28})$

7)    N3+X..30 => 7 => 240, 241, 250, 251, 400, 401, 403 => Oui => ^X([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,30})$

8)    N3+N..6 => 1 => 242 => Oui => ^242(\d{0,6})$

9)    N3+X..20 => 9 => 243, 254, 420, 710, 711, 712, 713, 714, 715 => Oui =>     ^X([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,20})$

10)    N3+N13[+X..17] => 1 => 253 => Oui => ^253(\d{13})([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,17})$

11)    N3+N13[+N..12] => 1 =>255 => Oui => ^255(\d{13})(\d{0,12})$

12)    N2+N..8 => 2 => 30, 37 => Oui => ^X(\d{0,8})$

13)    N4+N6 => 331 => 3100 à 3105, 3110 à 3115, 3120 à 3125, 3130 à 3135, 3140 à 3145, 3150 à 3155, 3160 à 3165,
 
    3200 à 3205, 3210 à 3215, 3220 à 3225, 3230 à 3235, 3240 à 3245, 3250 à 3255, 3260 à 3265, 3270 à 3275, 3280 à 3285, 3290 à 3295,
 
    3300 à 3305, 3310 à 3315, 3320 à 3325, 3330 à 335, 3340 à 3345, 3350 à 3355, 3360 à 3365, 3370 à 3375,

     3400 à 3405, 3410 à 3415, 3420 à 3425, 3430 à 3435, 3440 à 3445, 3450 à 3455, 3460 à 3465, 3470 à 3475, 3480 à 3485, 3490 à 3495,

    3500 à 3505, 3510 à 3515, 3520 à 3525, 3530 à 3535, 3540 à 3545, 3550 à 3555, 3560 à 3565, 3570 à 3575,

    3600 à 3605, 3610 à 3615, 3620 à 3625, 3630 à 3635, 3640 à 3645, 3650 à 3655, 3660 à 3665, 3670 à 3675, 3680 à 3685, 3690 à 3695,

    3950 à 3959,

    4326, 7006, 8005 => Oui => ^X(\d{6})$
 
14)    N4+N6..12 => 1 => 7007 => Oui => ^7007(\d{6,12})$

15)    N4+N6[+N..4] => 1 => 7011 => Oui => ^7011(\d{6})(\d{0,4})$

16)    N4+N..15 => 20 => 3900 à 3909, 3920 à 3929 => Oui => ^X(\d{0,15})$
 
17)    N4+N3+N..15 => 20 => 3910 à 3919, 3930 à 3939 => Oui => ^X(\d{3})(\d{0,15})$

18)    N4+N4 => 5 => 3940 à 3943, 8111 => Oui => ^X(\d{4})$

19)    N3+N17 => 1 => 402 => Oui => ^402(\d{17})$

20)    N3+N13 => 8 => 411 à 417 => Non => ^X(\d{13})$

21)    N3+N3+X..9 => 1 => 421 => Oui => ^421(\d{3})([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,9})$

22)    N3+N3 => 3 => 422, 424, 426 => Oui => ^X(\d{3})$

23)    N3+N3+N..12 => 2 => 423, 425 => Oui => ^X(\d{3})(\d{0,12})$

24)    N3+X..3 => 1 => 427 => Oui => ^427([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,3})$

25)    N4+X..35 => 5 => 4300, 4301, 4310, 4311, 4320 => Oui => ^X([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,35})$

26)    N4+X..70 => 13 => 4302 à 4306, 4312 à 4316, 8110, 8112, 8200 => Oui => ^X([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,70})$

27)    N4+X2 => 2 => 4307, 4317 => Oui => ^X([A-Z]{2})$

28)    N4+X2+X..28 => 10 => 7230 à 7239 => Oui => ^X([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{2,30})$

29)    N4+X..30 => 5 => 4308, 4319, 7002, 7023, 8004 => Oui => ^X([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,30})$

30)    N4+N20 => 1 => 4308 => Oui => ^4309(\d{20})$

31)    N4+X..20 => 7 => 4318, 7020, 7021, 7022, 7240, 8002, 8012 => Oui => ^X([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,20})$

32)    N4+N1 => 3 => 4321, 4322, 4323 => Oui => ^X([01])$

33)    N4+N10 => 3 =>4324, 4325, 7003 => Oui => ^X(\d{10})$

34)    N4+N13 => 1 => 7001 => Oui => ^7001(\d{13})$

35)    N3+N13 => 8 => 410 à 417 => Non => ^X(\d{13})$

36)    N4+X..12 => 1 => 7005 => Oui => ^7005([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,12})$

37)    N4+X..3 => 1 => 7008 => Oui => ^7008([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,3})$

38)    N4+N14+N2+N2 => 2 => 8006, 8026 => Oui => ^X(\d{14})(\d{2})(\d{2})$

39)    N4+X..34 => 1 => 8007 => Oui => ^8007([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,34})$

40)    N4+N8[+N..4] => 1 => 8008 => Oui => ^8008(\d{8})(\d{0,4})$

41)    N4+X..50 => 1 => 8009 => Oui => ^8009([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,50})$

42)    N4+Y..30 => 1 => 8010 => Oui => ^8010([\x23\x2D\x2F\x30-\x39\x41-\x5A]{5,30})$

43)    N4+X..10 => 1 => 7009 => Oui => ^7009([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,10})$

44)    N4+X..2 => 1 => 7010 => Oui => ^7010([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,2})$

45)    N4+N1+X3 => 1 => 7040 => Oui => ^7040(\d[\x21-\x22\x25-\x2F\x30-\x39\x41-\x5A\x5F\x61-\x7A]{3})$

46)    N4+N..12 => 1 => 8011 => Oui => ^8011(\d{0,12})$

47)    N4+N3+X..27 => 10 => 7030 à 7039 => Oui => ^X(\d{3})([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,27})$

48)    N4+N14 => 1 => 8001 => Oui => ^8001(\d{14})$

49)    N4+N14+X..16 => 1 => 8003 => Oui => ^8003(\d{14})([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,16})$

50)    N4+X..25 => 2 => 8013, 8020 => Oui => ^X([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,25})$

51)    N4+N18 => 2 => 8017, 8018 => Oui => ^X(\d{18})$

52)    N4+N..10 => 1 => 8019 => Oui => ^8019(\d{0,10})$

53)    N2+X..30 => 1 => 90 => Oui => ^90([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,30})$

54)    N2+X..90 => 9 => 91 à 99 => Oui => ^X([\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,90})$

-------------------------------------------------------------------------------------------------------------

Le groupe 13 couvre 331 balises et certains groupes en couvre qu'une!

0
Whismeril Messages postés 19039 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 7 mai 2024 656
26 oct. 2023 à 08:51

Oui mais toute ces regex partent du principe que les groupes sont déja découpées....


0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
26 oct. 2023 à 15:07

En s'inspirant du modèle:

pattern21 = "(\(?21\)?.{0,90}?)(?:GS|$|\x1d|\()"

Pour nouvelle la Balise 91, en adaptant les critères de recherche SG1:

pattern91= "(\(?91\)?.[\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,90}?)(?:GS|$|\x1d|\()"

Jusque-là c'est OK.

Pour les Balises 91 à 99 quelque chose comme ce qui suit pourrait marcher?

Balises9X = Array("91", "92", "93", "94", "95", "96", "97", "98", "99")
pattern9X= "(\(?)"+Balises9X+"(\)?.[\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,90}?)(?:GS|$|\x1d|\()"
0

Non, d'une part un tableau n'est pas une string et donc tu ne peux pas le concaténer comme ça et en plus il faut des "ou"

Un truc comme ça devrait fonctionner

pattern9X= "(\(?)9[1-9](\)?.[\x21-\x22\x25-\x2F\x30-\x39\x3A-\x3F\x41-\x5A\x5F\x61-\x7A]{0,90}?)(?:GS|$|\x1d|\()"

Mais ce que je crains, c'est que la regex devienne trop complexe et qu'elle ne fonctionne plus.

0
NeriXs Messages postés 258 Date d'inscription lundi 4 mai 2015 Statut Membre Dernière intervention 27 février 2024 1
26 oct. 2023 à 15:47

Je ne sais pas si c'est un problème avec la fonction:

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: "

        Case "91"
            madescription = "(91) InfosInternes: "
        
    End Select
           
    Description = madescription + LeCode
End Function

Case "91" ne s'affiche pas!

Testé avec:

010088483808258821DE7840AL79<GS>91867031

0
Rejoignez-nous