IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Delphi Discussion :

Trouver si des caractères sont dans une chaîne


Sujet :

Delphi

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Décembre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2016
    Messages : 7
    Points : 1
    Points
    1
    Par défaut Trouver si des caractères sont dans une chaîne
    Bonjour,

    D'abord merci à tous.

    Voici ce que j'essaye de faire : j'ai un fichier texte qui contient des lignes avec du texte et avec des suites numériques de 13 chiffres.
    Je veux ouvrir ce fichier et générer un autre qui contiendra que les suites numériques.

    Question : comment puis-je (je n'ai pas trouvé dans le site) trouver et garder les 13 chiffres qui se trouvent au milieu d'un texte et cela ligne par ligne ?

    J'ai déjà le fichier dans un Memo :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TForm1.Open1Click(Sender: TObject);
    begin
     
    assignfile(F1,opendialog1.FileName);                             
     
    if Opendialog1.Execute then
      Memo1.Lines.LoadFromFile(Opendialog1.FileName);
      Chemin:=ExtractFilePath(Opendialog1.FileName);                
    closefile(F1);
     
    end;
    *******************************

    Ensuite, j'essaye de garder dans "nuevalinea" 10 "codebar" pour écrire 10 codebar dans une ligne du Memo2

    Sachant que codebar est une suite de 13 chiffres mais qu'il y a pas d'ordre, j'essaye de trouver où se trouvent dans "linea" pour


    ****************************

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    procedure TForm1.Button1Click(Sender: TObject);
     
    var
    i,j,largolinea,numbercodes:integer;
     
    linea,partie,codebar,nuevalinea:string;
     
    begin
     
    for i:=0 to (Memo1.Lines.Count) do
    begin
        Assignfile(F1,opendialog1.FileName);
        Reset(F1);       
        Readln(F1,linea);
        largolinea:=Length(linea);
        for j:=1 to largolinea do
        begin
            partie:=copy(linea, j, 13);
                      if   partie[1]      in ['0','1','2','3','4','5','6','7','8','9'] 
                     and partie[2]      in ['0','1','2','3','4','5','6','7','8','9']
             and partie[3]      in ['0','1','2','3','4','5','6','7','8','9']
             and partie[4]      in ['0','1','2','3','4','5','6','7','8','9']
             and partie[5]       in ['0','1','2','3','4','5','6','7','8','9'] 
             and partie[6]       in ['0','1','2','3','4','5','6','7','8','9']
             and partie[7]       in ['0','1','2','3','4','5','6','7','8','9']
             and partie[8]       in ['0','1','2','3','4','5','6','7','8','9']
             and partie[9]       in ['0','1','2','3','4','5','6','7','8','9']
             and partie[10]     in ['0','1','2','3','4','5','6','7','8','9']
             and partie[11]     in ['0','1','2','3','4','5','6','7','8','9'] 
             and partie[12]     in ['0','1','2','3','4','5','6','7','8','9'] 
             and partie[13]     in ['0','1','2','3','4','5','6','7','8','9'] 
             and partie[14]not in ['0','1','2','3','4','5','6','7','8','9'] 
            then
              begin
                codebar:=partie;
                nuevalinea:=codebar+';';
                codebar:='';
                numbercodes:=numbercodes+1;
              end;
        end;
        if numbercodes=10;
            then
              begin
                Memo2.Text := (nuevalinea+';')
                nuevalinea:='';
        end;
    end;
    Merci beaucoup

    Cordialement

  2. #2
    Membre expérimenté
    Avatar de retwas
    Homme Profil pro
    Développeur Java/Delphi
    Inscrit en
    Mars 2010
    Messages
    698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Java/Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 698
    Points : 1 608
    Points
    1 608
    Billets dans le blog
    4
    Par défaut
    Si c'est jamais au même endroit c'est compliqué, il faut effectivement utiliser le Copy si tu es sur qu'il y est une seule suite de 13 caractères numériques par ligne correspondant à ton numéro.

    Tu peux utiliser un TryStrToInt ou IsNumeric sur ta variable partie plutôt que de tester chacun des caractères.

    Pour la première boucle il te manque le -1, je vois pas l'intérêt de la variable "codebar" tu peux t'en passer si c'est ton code complet.

    Si ton fichier est déjà chargé dans le memo pourquoi charger constamment le fichier et lire du coup que la première ligne ? Utilise la valeur de la ligne, Memo.Lines[i].

  3. #3
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2006
    Messages : 661
    Points : 3 630
    Points
    3 630
    Billets dans le blog
    2
    Par défaut
    Bonsoir,

    Quelle version de Delphi utilises tu ? Si c'est une version XE ou supérieure, tu peux utiliser les expressions régulières (voir l'excellent tutoriel de Roland Chastain : http://rchastain.developpez.com/tuto...arexpressions/).

    Si tu recherches une suite de 13 caractères numériques dans chaque lignes du memo, tu peux utiliser l'expression régulière \d{13} (=> on recherche 13 occurrences d'un caractère numérique).
    Mon site - Mes tutoriels - GitHub - N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 042
    Points : 40 955
    Points
    40 955
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    je plussoie gbreg et fait remarquer que avec D7 et l'installation de PerlRegex ça fonctionne aussi (donc pas forcément XE ou plus ) l'inclusion des expressions régulières dans Delphi s'est faite aux alentours des versions D2009-D2010 il me semble.
    Un sujet récent, dirigeant vers les expressions régulières et D7 peut être lu à partir du post #12
    Roland (qui a le courage et le temps ?) a fait d'excellentes FAQS
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  5. #5
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    mafdj2001 :Question, comment puis je (je n'ai pas trouvé dans le site) trouver et garder les 13 chiffres qui se trouvent au milieu d'un texte et cela ligne par ligne ?
    Sachant que codebar est une suite de 13 chiffres mais qu'il y a pas d'ordre, j'essaye de trouver ou se trouvent dans "linea"
    Quelle que soit la version Delphi, pour extraire une suite de chiffres d'une ligne de texte AlphaNumérique, je procéderais de la façon suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure TMainForm.Button1Click(Sender: TObject);
    var i, OrdChar: integer; Maligne, Mes13Chiffres: string;
    begin
      Maligne := 'TagadaTsoinTsoin5712364579451TrcuMuche';
      Mes13Chiffres := '';
      for i := 1 to length(MaLigne) do begin
        OrdChar := ord(MaLigne[i]);
        if (OrdChar < 48) or (OrdChar > 57) then Continue
        else Mes13Chiffres := Mes13Chiffres + MaLigne[i];
      end;
      showMessage(Maligne + #13#10 + Mes13Chiffres);
    end;
    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  6. #6
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Bonjour,

    il faudrait être sûr que le reste de la ligne ne contient pas quelques chiffres supplémentaires. mafdj2001 peut il envoyer un exemple de fichier contenant ces chaines ?

    A+
    Charly

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Décembre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2016
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    Bonjour,



    Quelle que soit la version Delphi, pour extraire une suite de chiffres d'une ligne de texte AlphaNumérique, je procéderais de la façon suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure TMainForm.Button1Click(Sender: TObject);
    var i, OrdChar: integer; Maligne, Mes13Chiffres: string;
    begin
      Maligne := 'TagadaTsoinTsoin5712364579451TrcuMuche';
      Mes13Chiffres := '';
      for i := 1 to length(MaLigne) do begin
        OrdChar := ord(MaLigne[i]);
        if (OrdChar < 48) or (OrdChar > 57) then Continue
        else Mes13Chiffres := Mes13Chiffres + MaLigne[i];
      end;
      showMessage(Maligne + #13#10 + Mes13Chiffres);
    end;
    A+.

    Ahh, oui, je vois, mais ce code recupère 14 ou 15 ou ... caractères alphanumeriques tant qu'ils le sont, et peu importe l'ordre a5b6c7451212121135132131 le resultat est : 5674..... alors que je ne veux que les code bar a 13 chiffres
    mais merci pour l'astuce qui peux servir en autre moment

  8. #8
    Nouveau Candidat au Club
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Décembre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2016
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par retwas Voir le message
    Si c'est jamais au même endroit c'est compliqué, il faut effectivement utiliser le Copy si tu es sur qu'il y est une seule suite de 13 caractères numériques par ligne correspondant à ton numéro.

    Tu peux utiliser un TryStrToInt ou IsNumeric sur ta variable partie plutôt que de tester chacun des caractères.

    Pour la première boucle il te manque le -1, je vois pas l'intérêt de la variable "codebar" tu peux t'en passer si c'est ton code complet.

    Si ton fichier est déjà chargé dans le memo pourquoi charger constamment le fichier et lire du coup que la première ligne ? Utilise la valeur de la ligne, Memo.Lines[i].
    Merci pour la reponse retwas, le code est pas complet, j'ai finalement reussit a trouver pourquoi les conditions ne marchaient pas (les () ) manquaient

    mais merci

  9. #9
    Nouveau Candidat au Club
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Décembre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2016
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    Bonjour,

    je plussoie gbreg et fait remarquer que avec D7 et l'installation de PerlRegex ça fonctionne aussi (donc pas forcément XE ou plus ) l'inclusion des expressions régulières dans Delphi s'est faite aux alentours des versions D2009-D2010 il me semble.
    Un sujet récent, dirigeant vers les expressions régulières et D7 peut être lu à partir du post #12
    Roland (qui a le courage et le temps ?) a fait d'excellentes FAQS

    Bonjour Gbreg et SergioMaster,

    merci pour cette info, je vais installer PerlRegex qui semble freeware ? , en effet ces expresions regulières sont une benediction, vivement le test

  10. #10
    Nouveau Candidat au Club
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Décembre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2016
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par Charly910 Voir le message
    Bonjour,

    il faudrait être sûr que le reste de la ligne ne contient pas quelques chiffres supplémentaires. mafdj2001 peut il envoyer un exemple de fichier contenant ces chaines ?

    A+
    Charly
    Bonjour Charly,

    Et malhereussement si, la ligne contiens d'autres chiffres, ça serait trop simple sinon, voici un fragment (le fichier peut avoir plusiers centaines de milier de lignes)

    Information - RETAILEAITRT00021 - Traitement - TRAITEMENT - ----> Traitement du fichier : \\RTLTSEPRDSTB1.gdm.group.root\Corbeilles\ORLI\DTPGISTOCK_FR_APLX1___20161212122415.TXT
    Warning - RETAILEAITRT00047 - Traitement - TRAITEMENT - La valeur GQ_DEPOT pour le champ 193 a été tronquée en 193.
    Information - RETAILEAISTK00004 - Stock - STOCK - ---> Suppression du stock du dépôt 193
    Warning - RETAILEAITRT00047 - Traitement - TRAITEMENT - La valeur GQ_DEPOT pour le champ 193 a été tronquée en 193.
    Warning - RETAILEAISTK00009 - Stock - STOCK - Disponible : DPA ou PMAP non renseigné pour l'article RB9196-00 001SJD X dans le dépôt 198
    Warning - RETAILEAITRT00047 - Traitement - TRAITEMENT - La valeur GQ_DEPOT pour le champ 198 a été tronquée en 198.
    Erreur - RETAILEAIART00008 - Article - STOCK - Le code-barres 9999984633704 ne correspond à aucun article
    Erreur - RETAILEAIART00011 - Article - STOCK - Identification de l'article impossible. Le code-barres ou le code article ne sont pas renseignés.
    Erreur - RETAILEAIART00034 - Article - STOCK - Disponible : l'article n'est pas renseigné
    Warning - RETAILEAITRT00047 - Traitement - TRAITEMENT - La valeur GQ_DEPOT pour le champ 198 a été tronquée en 198.



    j'ai mis en Gras italique un exemple de ce que je dois exclure, 20161212122415 a 14 char et c'est une date
    alors que 9999984633704 est bien un code bar a 13 char...

    je vais tenter la reponse de gbreg et SergioMaster qui semble ne prendre la chaine QUE s'il s'agis d'une chaine de 13 digits continus ?

  11. #11
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Re-bonjour,

    Charly910 : il faudrait être sûr que le reste de la ligne ne contient pas quelques chiffres supplémentaires.
    Exact, mais d'après :
    1) la question posée :
    mafdj2001 : Question, comment puis je (je n'ai pas trouvé dans le site) trouver et garder les 13 chiffres qui se trouvent au milieu d'un texte et cela ligne par ligne ?
    et 2) cet extrait de son code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     largolinea:=Length(linea);
        for j:=1 to largolinea do
        begin
            partie:=copy(linea, j, 13);
    il parcourt lui aussi chaque ligne du début jusqu'à sa fin, donc il semble déjà que ses 13 chiffres ne sont pas exactement au milieu, sinon il aurait écrit : for j:=(largolinea div 2) to largolinea do
    par contre partie:=copy(linea, j, 13) signifie que les chiffres sont acollés.

    Donc voici une variante qui extrait les 13 chiffres acollés même dans le cas où le texte de la ligne Maligne contient quelques chiffres supplémentaires comme ci-après:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    procedure TMainForm.Button1Click(Sender: TObject);
    label Recomm;
    var i, OrdChar, nChars: integer; Maligne, Mes13Chiffres: string;
    begin
      Maligne := 'Ta12gadaTsoinTsoin5710364579451TrucMu795che';
      Mes13Chiffres := '';
      i := 1;
      Recomm:
      OrdChar := ord(MaLigne[i]); nChars := 0;
      while (OrdChar < 48) or (OrdChar > 57) do begin
      inc(i); OrdChar := ord(MaLigne[i]);
      end;
      while (OrdChar >= 48) and (OrdChar <= 57) do begin
        Mes13Chiffres := Mes13Chiffres + MaLigne[i];
        inc(nChars); inc(i); OrdChar := ord(MaLigne[i]);
      end;
      if nChars < 13 then begin
        inc(i); Mes13Chiffres := ''; goto Recomm;
      end;
      if nChars = 13 then showMessage(Maligne + #13#10 + Mes13Chiffres);
    end;
    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  12. #12
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Bonjour,

    sinon voici le code de Gilbert sans les labels et goto :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    procedure TForm1.Button1Click(Sender: TObject);
    var i, OrdChar, nChars: integer; Maligne, Mes13Chiffres: string;
    begin
      Maligne := 'Ta12gadaTsoinTsoin5710364579451TrucMu795che';
      Mes13Chiffres := '';
      nChars := 0 ;
      For i := 1 to length(Maligne) do
         Begin
            OrdChar := ord(MaLigne[i]);
            If (OrdChar >= 48) And (OrdChar <= 57) Then
               Begin
                  Mes13Chiffres := Mes13Chiffres + MaLigne[i] ;
                  nChars := nChars + 1 ;
                  If (nChars = 13) Then showMessage(Maligne + #13#10 + Mes13Chiffres);
     
              End
            Else
               Begin
                  Mes13Chiffres := '' ;
                  nChars := 0 ;
               End ;
         End ;
    end ;
    A+

    Charly

  13. #13
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2006
    Messages : 661
    Points : 3 630
    Points
    3 630
    Billets dans le blog
    2
    Par défaut
    Bonsoir,

    Vous vous embêtez bien
    Avec les regexp, c'est simple et rapide :
    Imaginons notre form avec un bouton et deux mémos : le premier contient les lignes exemples fournies par mafdj2001, le second est vide et contiendra les résultats de la recherche (ce qui a "matché" avec l'expression régulière).

    Le clic sur le bouton va lancer la recherche. Voici un exemple de code (utilisant les expressions régulières fournies en standard avec Delphi (Berlin dans mon cas), mais avec PerlRegExp on doit pouvoir avoir quelque chose de similaire):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    var
      expr: TRegEx;
      collection: TMatchCollection;
      i : integer;
    begin
      // On efface le contenu du mémo des résultats
      memo2.Clear;
     
      // Expression régulière à rechercher : un caractère non numérique suivi de 13 caractères numériques et d'un caractère non numétique
      expr.Create('\D\d{13}\D');
     
      // Lancement de la recherche qui impacte tout le contenu de memo1
      collection := expr.Matches(Memo1.Lines.Text);
     
      // On parcourt la collection, et on met dans memo2 les valeurs qui ont "matché" avec l'expression régulière
      for i := 0 to collection.Count - 1 do
          memo2.Lines.Add(collection[i].Value);
    Mon site - Mes tutoriels - GitHub - N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  14. #14
    Nouveau Candidat au Club
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Décembre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2016
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par gbegreg Voir le message
    Bonsoir,

    Vous vous embêtez bien
    Avec les regexp, c'est simple et rapide :
    Imaginons notre form avec un bouton et deux mémos : le premier contient les lignes exemples fournies par mafdj2001, le second est vide et contiendra les résultats de la recherche (ce qui a "matché" avec l'expression régulière).

    Le clic sur le bouton va lancer la recherche. Voici un exemple de code (utilisant les expressions régulières fournies en standard avec Delphi (Berlin dans mon cas), mais avec PerlRegExp on doit pouvoir avoir quelque chose de similaire):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    var
      expr: TRegEx;
      collection: TMatchCollection;
      i : integer;
    begin
      // On efface le contenu du mémo des résultats
      memo2.Clear;
     
      // Expression régulière à rechercher : un caractère non numérique suivi de 13 caractères numériques et d'un caractère non numétique
      expr.Create('\D\d{13}\D');
     
      // Lancement de la recherche qui impacte tout le contenu de memo1
      collection := expr.Matches(Memo1.Lines.Text);
     
      // On parcourt la collection, et on met dans memo2 les valeurs qui ont "matché" avec l'expression régulière
      for i := 0 to collection.Count - 1 do
          memo2.Lines.Add(collection[i].Value);
    Hum,
    Très intéressant.
    Si ça tourne sur Delphi7, ça me paraît une des solutions les plus courtes.
    Je vais tester cela

    Merci beaucoup

  15. #15
    Nouveau Candidat au Club
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Décembre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2016
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par Charly910 Voir le message
    Bonjour,

    sinon voici le code de Gilbert sans les labels et goto :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    procedure TForm1.Button1Click(Sender: TObject);
    var i, OrdChar, nChars: integer; Maligne, Mes13Chiffres: string;
    begin
      Maligne := 'Ta12gadaTsoinTsoin5710364579451TrucMu795che';
      Mes13Chiffres := '';
      nChars := 0 ;
      For i := 1 to length(Maligne) do
         Begin
            OrdChar := ord(MaLigne[i]);
            If (OrdChar >= 48) And (OrdChar <= 57) Then
               Begin
                  Mes13Chiffres := Mes13Chiffres + MaLigne[i] ;
                  nChars := nChars + 1 ;
                  If (nChars = 13) Then showMessage(Maligne + #13#10 + Mes13Chiffres);
     
              End
            Else
               Begin
                  Mes13Chiffres := '' ;
                  nChars := 0 ;
               End ;
         End ;
    end ;
    A+

    Charly
    Bonsoir,

    merci beaucoup, mais ce code se confirme de prendre 13 digits de suite, même si la chaine contient une suite de 14 ou plus ce code ne fera pas la différence, or c'est un de requis
    mais merci

  16. #16
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 042
    Points : 40 955
    Points
    40 955
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    je plussoie la réponse de gbegreg,
    une remarque sur l'expression toutefois, elle ne prend pas en compte
    1-les 13 chiffres en début de ligne
    2-les 13 chiffres en fin de ligne
    -> mais rien que des alternatives ne puisse gérer

    et il peut aussi y avoir le cas de 2 fois 13 chiffres !
    -> mais rien qu'une numérotation de groupe ne puisse gérer

    Quelque chose comme \D(?<mesChiffres>\d{13})\D|^(?<mesChiffres>\d{13})\D|\D(?<mesChiffres>\d{13})$|^(?<mesChiffres>\d{13})$ATTENTION cette expression n'est pas testée avec l'unité PerlRegEx (ni XE, uniquement avec Expresso) , et je n'ai pas inclus le cas de la répétition

    maintenant si je regarde le texte de départ, puisque vous voulez semble t-il gérer les erreurs rien n'empêche de tester dans l'expression le fait que la ligne commence par : 'Erreur'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ^Erreur.\D\(?<meschiffres>\d{13})\D
    pourrait aussi faire l'affaire ?

    bref les expressions régulières ont de multiples possibilités pourvu de bien les maitriser, un art qui n'est pas encore à mon arc
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  17. #17
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    mafdj2001 : mais ce code se confirme de prendre 13 digits de suite, même si la chaine contient une suite de 14 ou plus ce code ne fera pas la différence, or c'est un de requis
    OK, voici une variante où la function fMes13Chiffres ignore les suites de chiffres de longueur différente de 13 et qui fonctionne lorsque les 13 chiffres sont en début et/ou en fin de ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    function fMes13Chiffres(const MaLigne: string): string;
    label Recomm;
    var i, OrdChar, nChars: integer;
    begin
      Result := ''; if MaLigne = '' then EXIT;
      i := 1;
      Recomm:
      OrdChar := ord(MaLigne[i]); nChars := 0;
      while (OrdChar < 48) or (OrdChar > 57) do begin
        inc(i); OrdChar := ord(MaLigne[i]);
      end;
      while (OrdChar >= 48) and (OrdChar <= 57) do begin
        Result := Result + MaLigne[i];
        inc(nChars); inc(i); OrdChar := ord(MaLigne[i]);
      end;
      if nChars = 13 then EXIT
      else begin
        Result := '';
        if i >= length(MaLigne) then EXIT
        else begin
          inc(i); goto Recomm;
        end;
      end;
    end;
    J'ai conservé le label Recomm et le goto vu que le code cette fonction est très court.
    Dans le cas où une ligne pourrait contenir plusieurs suites de 13 chiffres, tout d'abord il faudrait que mafdj2001 nous le dise,
    et ensuite il suffirait de modifier la function fMes13Chiffres de sorte qu'elle renvoie une StringList.

    Utilisation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TMainForm.Button1Click(Sender: TObject);
    var Maligne, Mes13Chiffres: string;
    begin
      Maligne := 'Ta0123456789012345gadaTsoinTsoin5710364579451TrucMu795che'; // < Ligne avec une seule suite de 13 chiffres précédée par une suite de 15 chiffres
      //Maligne := 'Ta0123456789012345gadaTsoinTsoin5710364579451458TrucMu795che'; // < Ligne avec plusieurs suites de chiffres de longueurs différentes de 13
      //Maligne := '5710364579451'; // < Ligne avec une seule suite de 13 chiffres située en début et/ou en fin de ligne
      Mes13Chiffres := fMes13Chiffres(MaLigne);
      if Mes13Chiffres <> ''
      then showMessage(Maligne + #13#10 + Mes13Chiffres)
      else showMessage('Ligne sans aucune suite de 13 chiffres');;
    end;
    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  18. #18
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Bonjour,

    voici le code modifié pour détecter la première séquence de 13 digits (y compris en début ou fin de chaine) et pas plus :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    procedure TForm1.Button1Click(Sender: TObject);
     
    Function  IsNumeric(Caractere : Char) : Boolean ;
    Var  OrdChar : Integer ;
    Begin
       OrdChar := ord(Caractere);
       Result := (OrdChar >= 48) And (OrdChar <= 57) ;
    End ;
    { ------------------------------------------- }
    var i, nChars: integer; Maligne, Mes13Chiffres: string;
        Trouve  : Boolean ;
    begin
      Maligne := 'Ta12345678912345678912345gadaTsoinTsoin5710364579451TrucMu795che';
      Mes13Chiffres := '';
      nChars := 0 ;
      Trouve := False ;
      For i := 1 to length(Maligne) do
         Begin
            If IsNumeric(MaLigne[i]) Then
               Begin
                  Mes13Chiffres := Mes13Chiffres + MaLigne[i] ;
                  nChars := nChars + 1 ;
                  // 13 eme caractere numérique
                  If (nChars = 13) Then
                     Begin
                        // on est en fin de chaine
                        If (i = length(Maligne)) Then
                           Begin
                              Trouve := True ;
                              Break ;
                           End ;
                        // Caractere suivant numérique ?
                        If not IsNumeric(MaLigne[i+1]) Then
                           Begin
                              Trouve := True ;
                              Break ;
                           End
                        Else
                           // il y a 14 caractères numériques de suite
                           Begin
                              Mes13Chiffres := '' ;
                              nChars := 0 ;
                           End ;
                     End ;
              End
            Else
               Begin
                  Mes13Chiffres := '' ;
                  nChars := 0 ;
               End ;
         End ;
         If Trouve Then  ShowMessage(Maligne + #13#10 + Mes13Chiffres)
                   Else  ShowMessage('Pas de codebar trouvé dans la ligne'+
                         #13#10 + MaLigne) ;
    end ;
    Mais je pense effectivement que le RegEx est plus puissant et préférable que cette bidouille !!
    A+
    Charly

  19. #19
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    RE,

    Exemple s'il faut gérer des erreurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    procedure TMainForm.Button1Click(Sender: TObject);
    var Maligne, Mes13Chiffres: string;
    begin
      //Maligne := 'Ta0123456789012345gadaTsoinTsoin5710364579451TrucMu795che'; // < Ligne avec une seule suite de 13 chiffres précédée par une suite de 15 chiffres
      //Maligne := 'Ta0123456789012345gadaTsoinTsoin5710364579451458TrucMu795che'; // < Ligne avec plusieurs suites de chiffres de longueurs différentes de 13
      //Maligne := '5710364579451pp'; // < Ligne avec une seule suite de 13 chiffres située en début et/ou en fin de ligne
      //Maligne := 'Information - RETAILEAITRT00021 - Traitement - TRAITEMENT - ----> Traitement du fichier : \\RTLTSEPRDSTB1.gdm.group.root\Corbeilles\ORLI\DTPGISTOCK_FR_APLX1___20161212122415.TXT'; //< Ligne avec suite de chiffres de longueur différente de 13
      Maligne := 'Erreur - RETAILEAIART00008 - Article - STOCK - Le code-barres 9999984633704 ne correspond à aucun article';
      Mes13Chiffres := fMes13Chiffres(MaLigne);
      if Mes13Chiffres <> '' then begin
       if pos('Erreur',MaLigne) = 0
       then showMessage(Maligne + #13#10 + Mes13Chiffres)
       else showMessage(Maligne + #13#10 + Mes13Chiffres+' <- code-barres Erreur');
      end
      else showMessage(Maligne+' <= Ligne sans aucune suite de 13 chiffres');;
    end;
    Reste à savoir quels types d'erreurs il faut détecter ou lesquels il faut ignorer : lol.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  20. #20
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2006
    Messages : 661
    Points : 3 630
    Points
    3 630
    Billets dans le blog
    2
    Par défaut
    Effectivement SergioMaster, dans mon exemple, j'étais allé au plus simple. L'expression régulière doit être adaptée en fonction des différents cas possibles mais cela n'est pas bien compliqué : l'expression régulière change mais le code reste le même.

    De plus, un autre avantage des expressions régulières, c'est qu'on pourrait externaliser l'expression dans un fichier de paramétrage : ainsi, il suffit de peaufiner l'expression dans le fichier de paramétrage et on relance le programme : pas besoin de toucher au code et à recompiler le programme...
    Mon site - Mes tutoriels - GitHub - N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

Discussions similaires

  1. Problème avec des caractères spéciaux dans une chaine
    Par thibaut06 dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 20/11/2006, 16h46
  2. [C#] Comment insérer des retours chariot dans une chaine de caractère ?
    Par tazmania dans le forum Accès aux données
    Réponses: 4
    Dernier message: 30/10/2006, 09h27
  3. Réponses: 3
    Dernier message: 24/04/2006, 15h53
  4. Réponses: 11
    Dernier message: 25/09/2005, 21h20
  5. Réponses: 2
    Dernier message: 12/01/2004, 13h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo