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

Langage Delphi Discussion :

[D7] WideStringReplace


Sujet :

Langage Delphi

  1. #1
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 085
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 085
    Points : 886
    Points
    886
    Par défaut [D7] WideStringReplace
    Bonjour,

    Je suis actuellement sur un projet qui manipule de l'unicode et je cherche une fonction de remplacement de chainet de texte.

    Mais bon, Delphi 7 n'est pas très à l'aise avec l'unicode ou plutôt n'offre pas des tas de bibliothèques qui permet de le manipuler.

    J'ai vu qu'il y avait le compo TNT mais je ne souhaite vraiment pas utiliser de composants non standard dans ce projet.

    Avez-vous sous le coude un fonction que fait celà ?

    Merci d'avance

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 534
    Points : 25 082
    Points
    25 082
    Par défaut
    StringReplace, tu as le code dans SysUtils, tu remplace string par WideString dans tout le code
    AnsiUpperCase par WideUpperCase

    AnsiPos tu la réécris en WidePos (utilise l'algo de PosEx dans StrUtils, suffit de remplace string par WideString, et d'enlever l'appel à Pos)

    Copy si tu manque de confiance, remplace par CopyMemory en considérant la taille du char à 2

    Tu devrais pouvoir nous finir quelques chose de sympa, en fouillant sur Koders, tu pourras aussi trouver les fonctions qui manque pour refaire AnsiPos en WidePos (avec l'algo d'origine de AnsiPos et non celui de PosEx)
    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 éclairé

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 085
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 085
    Points : 886
    Points
    886
    Par défaut
    OK Merci, je vais essayer de faire ça !

  4. #4
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 085
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 085
    Points : 886
    Points
    886
    Par défaut
    Ca à l'air de marcher. Voici le code :
    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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    function WidePos(const SubStr, S: WideString): Integer;
    var
      I,X: Integer;
      Len, LenSubStr: Integer;
    begin
        I := 1;
        LenSubStr := Length(SubStr);
        Len := Length(S) - LenSubStr + 1;
        while I <= Len do
        begin
          if S[I] = SubStr[1] then
          begin
            X := 1;
            while (X < LenSubStr) and (S[I + X] = SubStr[X + 1]) do
              Inc(X);
            if (X = LenSubStr) then
            begin
              Result := I;
              exit;
            end;
          end;
          Inc(I);
        end;
        Result := 0;
    end;
    function WCopy(const S : WideString;index : Integer; Count : Integer):WideString;
    var
      R : widestring;
    begin
      SetLength(R,Count);
      CopyMemory(PWideChar(R),PWideChar(S)+Index-1,Count*2);
      Result := R;
    end;
    function WideStringReplace(const S, OldPattern, NewPattern: WideString;
      Flags: TReplaceFlags): WideString;
    var
      SearchStr, Patt, NewStr: WideString;
      Offset: Integer;
    begin
      if rfIgnoreCase in Flags then
      begin
        SearchStr := WideUpperCase(S);
        Patt := WideUpperCase(OldPattern);
      end else
      begin
        SearchStr := S;
        Patt := OldPattern;
      end;
      NewStr := S;
      Result := '';
      while SearchStr <> '' do
      begin
        Offset := WidePos(Patt, SearchStr);
        if Offset = 0 then
        begin
          Result := Result + NewStr;
          Break;
        end;
        Result := Result + WCopy(NewStr, 1, Offset - 1) + NewPattern;
        NewStr := WCopy(NewStr, Offset + Length(OldPattern), Length(S)-Offset-Length(OldPattern)+1);
        if not (rfReplaceAll in Flags) then
        begin
          Result := Result + NewStr;
          Break;
        end;
        SearchStr := WCopy(SearchStr, Offset + Length(Patt), Length(S)-Offset-Length(OldPattern)+1);
      end;
    end;
    Mais je ne suis pas très sûr du code de la fonction WCopy...

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 534
    Points : 25 082
    Points
    25 082
    Par défaut
    Tu dois pouvoir simplifier mais cela me semble bien !
    Tu dois pouvoir accéder à l'adresse dans S via [], à tester

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function WCopy(const S : WideString; index : Integer; Count: Integer):WideString;
    begin
      SetLength(Result, Count);
      CopyMemory(PWideChar(Result), PWideChar(S[Index]), Count * SizeOf(WideChar));
    end;
    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

  6. #6
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 085
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 085
    Points : 886
    Points
    886
    Par défaut
    OK parfait Merci.

    J'ai encore une petite question concernant unicode.
    J'essaie de charger un fichier UTF-8 dans un TMemoryStream. Jusque là OK. Mais quand je veux charger un var WideString, j'ai l'impression qu'il ne charge pas avec le bon codage. Quand j'inspecte la valeur , je vois des caractères du style "?????4???". Chose qui ne m'arrange pas vu que ma fonction WideStringReplace ne fonction pas dans ce cas de figure.

    Aurai-je oublié quelque chose ?

    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
      S : TMemoryStream;
      Content : WideString;
    begin
      S := TMemoryStream.Create;
      try
        S.LoadFromFile('c:\Test.xml');
        S.Position := 0;
        SetLength(Content,S.Size);
        S.Read(Content[1],Length(Content));
        S.Clear;
        Content := WideStringReplace(Content,'test','',[]);
        S.Write(Content[1],Length(Content));
        S.SaveToFile('c:\test.out');
      finally
        S.Free;
      end;

  7. #7
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 085
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 085
    Points : 886
    Points
    886
    Par défaut
    Mais en fait, UTF8 c'est codé sur 8 bits donc ça peut tenir dans un string non ?

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 534
    Points : 25 082
    Points
    25 082
    Par défaut
    Tu as le type UTF8String qui n'est ni plus ni moins une string que l'on manupile avec UTF8Decode et UTF8Encode
    ou Utf8ToUnicode pour un WideString (PWideChar)
    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

  9. #9
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 745
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 745
    Points : 13 306
    Points
    13 306
    Par défaut
    Citation Envoyé par portu Voir le message
    Quand j'inspecte la valeur , je vois des caractères du style "?????4???".
    Pas sûr que D7 puisse inspecter de l'unicode .

    Sinon, SetLength(Content,...) est 2x trop grand. Content attend une taille en WideChar, mais TMemoryStream.Size renvoie une taille en octet.

    Enfin, si ton fichier est unicode, il a peut-être un tag $FEFF en début de fichier. Il faudrait lire ce word en premier.

  10. #10
    Membre éclairé

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 085
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 085
    Points : 886
    Points
    886
    Par défaut
    Pfff quelle punition l'unicode avec delphi 7....

    Tant que j'y suis, je vais vous expliquer le but de mon travail (On ne sais jamais, peut être que quelqu'un aura une meilleure idée que la mienne).

    J'ai dans une table paradox (), un champ qui contient un document zippé xml codé en UTF8. A l'aide d'un XSL, je transforme le XML en HTML que j'affiche dans un TWebBrowser. J'utilise pour la transormation TXMLDocument et TXSL????.

    Jusqu'à présent, on me fournissait des xml en ISO-???? (latin-1) et je n'avais pas (trop) de problème.

    Maintenant, je ne sais pas si les composants TXMLDocument et TXSL???? peuvent contenir et générer de l'UTF8.

    Avez-vous déjà été confronté à ce genre de problèmes ?

    Merci

  11. #11
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    Le problèmefréquent avec Xml c'est les caractères d'accents mais le fait d'ajouter au début
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    <?xml  encoding="UTF-8"?>

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