web-dev-qa-db-fra.com

Delphi: TStringList Delimiter est toujours un caractère espace même si Delimiter est défini

J'ai des problèmes avec le délimiteur de la classe TStringList. Regarde:

var
  s: string;
  sl: TStringList;

begin
  sl := TStringList.Create;
  s := 'Users^foo bar^bar foo^foobar^barfoo';
  sl.Delimiter := '^';
  sl.DelimitedText := s;
  ShowMessage(sl[1]);
end;

sl[1] DEVRAIT retourner 'foo bar'

sl[1] RETOURNE 'foo'

Il semble que le délimiteur soit maintenant '^' ET ' '

Des idées?

54
Acron

Vous devez définir s1.StrictDelimiter := True pour les espaces à ne pas considérer comme délimiteurs, plus d'infos ici .

Puisque vous travaillez dans une version qui ne prend pas en charge ce qui précède (comme cela a été clarifié après la soumission de la réponse), vous avez deux options:

  1. Recherchez un caractère dont vous savez qu'il ne sera pas utilisé dans le texte d'origine (par exemple, le trait de soulignement), convertissez tous les espaces en ce caractère avant le fractionnement et reconvertissez après le fractionnement. C'est la suggestion de robosoft .
  2. Si vous n'avez pas de virgules et d'espaces inversés dans le texte, vous pouvez utiliser l'astuce de Alexander et encapsuler le texte entre les délimiteurs dans la commande inversée, de sorte que 'hello hello^bye bye' se tourne vers '"hello hello"^"bye bye"'. Si vous choisissez ce chemin et que cela fonctionne pour vous, veuillez accepter la réponse d'Alexandre et non la mienne, il fournit également le code pour l'implémenter.

Les deux solutions de contournement n'utilisant pas StrictDelimiter ont des limitations: la première nécessite un caractère inutilisé et la seconde ne nécessite ni virgule ni espace inversé dans le texte d'origine.

Il est peut-être temps de passer à une version plus récente de Delphi :)

83
Roee Adler
sl.DelimitedText := '"' + StringReplace(S, sl.Delimiter, '"' + sl.Delimiter + '"', [rfReplaceAll]) + '"';
18
Alex

Ryan a fourni une excellente solution à ce problème en utilisant la fonction ExtractStrings () dans Delphi. Voir:

L'analyse d'une chaîne à l'aide d'un délimiteur vers un TStringList, semble également analyser les espaces (Delphi)

Donc, dans votre cas, remplacez les appels à sl.Delimiter et sl.DelimitedText par la ligne ci-dessous: ExtractStrings (['^'], [], PChar (S), sl);

4
Kashif Raja
sl.Text := StringReplace(S, sl.Delimiter, sLineBreak, [rfReplaceAll]);
2
barbaris

Travaille en Delphi 7 "comme des gants" pour moi. C'est ma fonction après avoir appliqué le tour d'Alexandre:

procedure Split (const Delimiter: Char; Input: string; const Strings: TStrings) ;
begin
   Assert(Assigned(Strings)) ;
   Strings.Clear;
   Strings.Delimiter := Delimiter;
   Strings.DelimitedText :=  '"' + StringReplace(Input, Delimiter, '"' + Delimiter + '"', [rfReplaceAll]) + '"' ;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit1.Text := 'Users^foo bar^bar foo^foobar^barfoo';
  Split('^',Edit1.Text,Memo1.Lines);
end;

Merci beaucoup!

2
Ale Costa