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 :

Remplacement erratique de string


Sujet :

Delphi

  1. #1
    Membre chevronné
    Avatar de Droïde Système7
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    2 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 2 262
    Points : 1 928
    Points
    1 928
    Par défaut Remplacement erratique de string
    Bonjour

    Depuis un certain temps, j'ai le couvercle de ma marmite qui fume

    Bref, un petit problème qui à priori devrait être simple, puisque les tests en ShowMessages sont impeccables ; mais la réalité de la compile en est une autre.

    Je vous donne une version du principe afin de trouver ce qui foire :
    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
    procedure TForm1.Button1Click(Sender: TObject);
    var
      StringList, StringLine: TStringList;
      mot, AmotB: String;
      i, j: Integer;
    begin
      StringList := TStringList.Create; // En vertical = texte
      StringLine := TStringList.Create; // En horizontal = ligne
     
      TRY
        Memo1.Lines.LoadFromFile('Texte.txt');
        StringList.LoadFromFile ('Texte.txt');
     
        for i := 0 to StringList.Count - 1 do
        begin
     
          //------- Seconde StringList analysant mot à mot sur LA sLigne affectée
            StringLine.Text          := StringList[i];
            StringLine.Delimiter     := ' '; // Delimiteur = SPACE
            StringLine.QuoteChar     := ' ';
            StringLine.DelimitedText := StringLine.Text;
            //ShowMessage(StringList[i]);
          //-------
     
           for j := 0 to  StringLine.Count - 1 do
             if pos(AnsiLowerCase('toto'), StringLine[j]) > 0 then
             begin
               mot   := StringLine[j];
    //ShowMessage(mot); // Détection impec pourtant !
               AmotB := 'A'+mot+'B';
    //ShowMessage(AmotB); // Ici aussi impec !
             end;
     
             StringList[i] := StringReplace(StringList[i],   mot, AmotB, [rfReplaceAll, rfIgnoreCase]);
             //StringList[i] := StringReplace(StringList[i],   mot, AmotB, [rfIgnoreCase]);
             //StringList[i] := AnsiReplaceText(StringList[i], mot, AmotB);
             //StringList[i] := AnsiReplaceStr(StringList[i],  mot, AmotB);
        end;
     
        ShowMessage(StringList.Text);
        //Memo1.Text := StringList.Text;
      FINALLY
        StringLine.Free;
        StringList.Free;
      end;
    end;
    Voici également le texte de test allant avec :
    Essai numéro un : toto et totoriri totoririloulou ensuite ...

    Second essai : totoririloulou plus totoriri toto voilà !
    Le but recherché est exclusivement de détecter certains mots et de placer de part et d'autre une string, exemple basé sur le mot de recherche toto :
    AtotoririloulouB AtotoloulouB

    Toutes les étapes sont franchies avec succès, enfin... à en croire les ShowMessages.

    Car en réalité, les remplacements sont très erratiques. En effet ; les ajouts de strings s'effectuent même à l'intérieur des mots

    J'ai pourtant testé avec (presque) toutes les fonctions équivalentes à StringReplace() et consorts.

    Un grand merci d'avance de votre aide.

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 426
    Points : 24 790
    Points
    24 790
    Par défaut
    L'algo est faux puisque que le StringReplace est en dehors de la boucle, soit mauvais exemple soit source de ton problème

    Sinon ma fonction ExplodeLazy est beaucoup plus rapide pour découper une chaine ... par défaut un array of string, mais j'ai fait le wrapper pour fournir une TStrings si tu es plus à l'aise avec ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre chevronné
    Avatar de Droïde Système7
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    2 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 2 262
    Points : 1 928
    Points
    1 928
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    L'algo est faux puisque que le StringReplace est en dehors de la boucle, soit mauvais exemple soit source de ton problème

    Sinon ma fonction ExplodeLazy est beaucoup plus rapide pour découper une chaine ... par défaut un array of string, mais j'ai fait le wrapper pour fournir une TStrings si tu es plus à l'aise avec ...
    Merci à toi ShaiLeTroll de me donner d'autres cartouches, je vais approfondir cela, très très vite si jamais je ne trouve pas de solution au code de ce thread.

    Au sujet de la bouche, en effet... c'est un peu mieux, mais ça foire encore.
    Pourtant les ShowMessages indiquent bien que tout ronfle impec.
    Reste plus qu'à effectuer un remplacement de string. C'est un coup à se la dévorer (heuuu... la cravate )

    J'ai donc mieux positionné un "end" afin que le remplace soit intégré dans les boucles :

    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
    procedure TForm1.Button1Click(Sender: TObject);
    var
      StringList, StringLine: TStringList;
      mot, AmotB: String;
      i, j: Integer;
    begin
      StringList := TStringList.Create; // En vertical = texte
      StringLine := TStringList.Create; // En horizontal = ligne
     
      TRY
        Memo1.Lines.LoadFromFile('Texte.txt');
        StringList.LoadFromFile ('Texte.txt');
     
        for i := 0 to StringList.Count - 1 do
        begin
     
          //------- Seconde StringList analysant mot à mot sur LA sLigne affectée
            StringLine.Text          := StringList[i];
            StringLine.Delimiter     := ' '; // Delimiteur = SPACE
            StringLine.QuoteChar     := ' ';
            StringLine.DelimitedText := StringLine.Text;
            //ShowMessage(StringList[i]);
          //-------
     
           for j := 0 to  StringLine.Count - 1 do
             if pos(AnsiLowerCase('toto'), StringLine[j]) > 0 then
             begin
               mot   := StringLine[j];
    //ShowMessage(mot); // Détection impec pourtant !
               AmotB := 'A'+mot+'B';
    //ShowMessage(AmotB); // Ici aussi impec !
     
     
             StringList[i] := StringReplace(StringList[i],   mot, AmotB, [rfReplaceAll, rfIgnoreCase]);
             //StringList[i] := StringReplace(StringList[i],   mot, AmotB, [rfIgnoreCase]);
             //StringList[i] := AnsiReplaceText(StringList[i], mot, AmotB);
             //StringList[i] := AnsiReplaceStr(StringList[i],  mot, AmotB);
             end; // boucle j
     
        end; // boucle i
     
        ShowMessage(StringList.Text);
        //Memo1.Text := StringList.Text;
      FINALLY
        StringLine.Free;
        StringList.Free;
      end;
    end;
    Pourquoi donc, tout est impec et foire exclusivement lors de remplacements ?

    @+

  4. #4
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    Citation Envoyé par Droïde Système7
    Pourquoi donc, tout est impec et foire exclusivement lors de remplacements ?
    les Showmessage() qui sont impec sont basés sur StringLine[j]
    alors que tu fait le remplacement sur StringList[i]
    je crois que ton problème ce situe à ce niveau...

    si tu affiche StringList[i] dans un showMessage, avant
    et apres stringReplace...tu verra bien que StringReplace() fait
    bien sont travail...
    Comment dupliquer un disque...ça vous intéresse?
    Tutoriel et code source delphi ici

  5. #5
    Membre chevronné
    Avatar de Droïde Système7
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    2 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 2 262
    Points : 1 928
    Points
    1 928
    Par défaut
    Bonjour et merci Éric,

    Vu le temps que j'ai passé dessus, je peux te dire que les fonctions de remplacements foirent (plus ou moins toutes). Enfin surtout celle à portées strictes, qui sont off course.

    Exemple via la petite modif du code suivant qui démontre que dans un sens ça fonctionne impec, mais dans l'autre ça foire à plein tube

    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
    procedure TForm1.Button1Click(Sender: TObject);
    var
      StringList, StringLine: TStringList;
      mot, AmotB: String;
      i, j: Integer;
    begin
      StringList := TStringList.Create; // En vertical = texte
      StringLine := TStringList.Create; // En horizontal = ligne
     
      TRY
        Memo1.Lines.LoadFromFile('Texte.txt');
        StringList.LoadFromFile ('Texte.txt');
     
        for i := 0 to StringList.Count - 1 do
        begin
     
          //------- Seconde StringList analysant mot à mot sur LA sLigne affectée
            StringLine.Text          := StringList[i];
            StringLine.Delimiter     := ' '; // Delimiteur = SPACE
            StringLine.QuoteChar     := ' ';
            StringLine.DelimitedText := StringLine.Text;
            //ShowMessage(StringList[i]);
          //-------
     
           for j := 0 to  StringLine.Count - 1 do
             if pos(AnsiLowerCase('toto'), StringLine[j]) > 0 then
             begin
               mot   := StringLine[j];
    //ShowMessage(mot); // Détection impec pourtant !
               AmotB := 'A'+mot+'B';
    //ShowMessage(AmotB); // Ici aussi impec !
     
     
             //StringList[i] := StringReplace(StringList[i],   mot, AmotB, [rfReplaceAll, rfIgnoreCase]);
             StringList[i] := StringReplace(StringList[i],   mot, AmotB, [rfIgnoreCase]);
    ShowMessage('StringList[i] :  ' +StringList[i]);
             //StringList[i] := AnsiReplaceText(StringList[i], mot, AmotB);
             //StringList[i] := AnsiReplaceStr(StringList[i],  mot, AmotB);
             end; // boucle j
     
        end; // boucle i
     
        //ShowMessage(StringList.Text);
        Memo1.Text := StringList.Text;
      FINALLY
        StringLine.Free;
        StringList.Free;
      end;
    end;
    Hé oui par exemple dans :

    toto totoriri... c'est impec, mais par contre niet dans le sens contraire :
    totoriri, toto

    En électronique cela se nomme un effet de rémanence, en informatique, je ne sais pas ; peut-être une variable mal affectée.

    Ceci dit, tu avais raison au sujet de mes ShowMessages donnant des info impec

    @+

  6. #6
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    je te propose ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    If pos(AnsiLowerCase('toto'), StringLine[j]) > 0 Then
            Begin
              mot := StringLine[j];
              AmotB := 'A' + mot + 'B';
              //== Il doit y avoir au moins un espace avant ou après sinon, ==
              //== on en remplace pluseurs! ==
              StringList[i] := StringReplace(StringList[i], ' '+mot, ' '+AmotB, [rfIgnoreCase]);
              StringList[i] := StringReplace(StringList[i], mot+' ', AmotB+' ', [rfIgnoreCase]);
            End; // boucle j

    EDITION: AJOUT de voici ce qui ce passe:
    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
     
    //== ici ton erreur ==
    // 1ere passe
    a:='toto totolala'
    a:=StringReplace(a,'toto','AtotoB',[rfIgnoreCase])
    //a='AtotoB AtotoBlala' est c'est normal! Résultat non souhaité
    // 2eme passe
    a:='AtotoB AtotoBlala'
    a:=StringReplace(a,'totolala','AtotolalaB',[rfIgnoreCase])
    //a= 'AtotoB AtotoBlala' aucun remplacement, Résultat non souhaité
     
     
     
    //=========================
    //== Ici on ajoute un espace avant et apres avec 2 appèle à StringReplace
    // 1ere passe
    a:='toto totolala'
    a:=StringReplace(a,' '+'toto',' '+'AtotoB',[rfIgnoreCase])
    //a='toto totolala' est c'est normal! et resultat souhaité
    a:=StringReplace(a,'toto'+' ','AtotoB'+' ',[rfIgnoreCase])
    //a:='AtotoB totolala' est bon et resultat souhaité
     
    // 2eme passe
    a:='AtotoB totolala'
    a:=StringReplace(a,' '+'totolala',' '+'AtotolalaB',[rfIgnoreCase])
    //a='AtotoB AtotolalaB' est c'est normal! et resultat souhaité
    a:=StringReplace(a,'totolala'+' ','AtotolalaB'+' ',[rfIgnoreCase])
    //a:='AtotoB AtotolalaB' aucun remplacement n'est fait et resultat souhaité
    Comment dupliquer un disque...ça vous intéresse?
    Tutoriel et code source delphi ici

  7. #7
    Membre chevronné
    Avatar de Droïde Système7
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    2 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 2 262
    Points : 1 928
    Points
    1 928
    Par défaut


    Merci Éric, encore une fois que tu me dépannes !

    Oui, grâce à tes rectifs, désormais ça tourne impec et dans les deux sens.

    J'ai en prime les explications du pourquoi ça foirait

    Encore

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Remplacer dans un String ^ par Math.pow
    Par Rhada2007 dans le forum Langage
    Réponses: 3
    Dernier message: 08/07/2011, 15h47
  2. [PowerShell] remplacement de here-string
    Par beyo dans le forum Scripts/Batch
    Réponses: 2
    Dernier message: 26/06/2011, 16h46
  3. Remplacer char dans string par code ASCII
    Par ThomasParis dans le forum Langage
    Réponses: 2
    Dernier message: 16/07/2010, 12h47
  4. Remplacement dans un String
    Par JCD21 dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 16/03/2010, 14h48
  5. Remplacement spécial de string dans un fichier
    Par elitost dans le forum Shell et commandes GNU
    Réponses: 6
    Dernier message: 27/09/2007, 17h27

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