Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi String zerlegen; Trenner (https://www.delphipraxis.net/102107-string-zerlegen%3B-trenner.html)

KPBecker 23. Okt 2007 15:46


String zerlegen; Trenner
 
Hallo, Delphi-Praktiker,

ich erinnere mich, daß es für Stringlists die Möglichkeit gibt, Substrings anhand eines Trenners zu extrahieren. (SirThornberry erwähnt das auch in einem Beitrag vom 17.07.2004)

Bloß: Ich finde diese Funktion nicht.
Wie heißt das Ding ?

Betste Grüße
Klaus-Peter

Phoenix 23. Okt 2007 15:48

Re: String zerlegen; Trenner
 
Du musst den .Delimiter setzen (Trennzeichen) und sagst dann Liste.DelimitedText := 'Dein;Text'.
Den Rest macht die Liste von alleine.

Allerdings habe ich die Erfahrung gemacht, dass die TStringList auch gerne bei sonstigen Trennern wie Leerzeichen, Kommas, Semikola im Text trennt, auch wenn in Delimiter was anderes festgelegt war.

SirThornberry 23. Okt 2007 15:49

Re: String zerlegen; Trenner
 
hier ist das ding:
http://www.delphipraxis.net/internal...=205244#205244

mkinzler 23. Okt 2007 15:53

Re: String zerlegen; Trenner
 
Delphi-Quellcode:
var
  sl: TStrings;
...
begin
   sl := TStringList.Create;
   ...
   sl.delimiter := '<Trennzeichen>';
   sl.DelimitedText := '<Text>';
   s1 := sl.Strings[0]; //1. Teilstring
   s2 := sl.Strings[1]; //2. Teilstring
...
Aber Achtung: Leerzeichen führen zusätzlich zur Trennung

KPBecker 23. Okt 2007 15:56

Re: String zerlegen; Trenner
 
Zitat:

Zitat von SirThornberry

Das ist die Eigenentwicklung von Dir, die ich zitierte.
Frage: Wie heißt die Delphi-eigene Funktion, auf die Du dort hinweist ?

Den Tip von Sebastian schaue ich mir an.

Klaus-Peter

Phoenix 23. Okt 2007 15:59

Re: String zerlegen; Trenner
 
Das ist genau das. Und mein Tip ist das gleiche, was mKinzler mit Beispielcode geliefert hat.
Delimiter setzen, Text zuweisen, fertig. Aber das geht glaub ich erst seit Delphi 5.

KPBecker 23. Okt 2007 16:25

Re: String zerlegen; Trenner
 
Hallo,

im Prinzip ist Alles prima, der Tip von mkinzler und Sebastian läuft, aber ...

Sebastian hat leider recht:
Als Trenner habe ich '|' gesetzt, aber das Blank wird auch als (zusätzlicher) Trenner interpretiert.
(It's not a bug, it's a feature ???)

1. Was soll der Unsinn (der es doch wohl ist) ?
2. Kann man das sl.DelimitedText:= <Text> trotzdem zu sinnvollem Laufen bringen ?

Klaus-Peter

Apollonius 23. Okt 2007 16:28

Re: String zerlegen; Trenner
 
Eine reichlich arme Lösung wäre ein davorgesetztes StringReplace, das die Leerzeichen entweder ganz entfernt, wenn sie nicht benötigt werden, oder aber die Leerzeichen in wenig genutzte Symbole verwandelt, falls du sie brauchst. Du solltest im letzteren Fall allerdings noch über die Strings iterieren und die Ersetzung wieder rückgängig machen, sofern dann keine neue Trennung durchgeführt wird. Wie gesagt, reichlich arm.

KPBecker 23. Okt 2007 16:32

Re: String zerlegen; Trenner
 
Hallo, Philip,

die Eleganz läßt, wie du richtig sagst, dabei sicher zu wünschen übrig.
Man könnte dann fast diese Funktion wieder selbst schreiben.

Klaus-Peter

Apollonius 23. Okt 2007 16:37

Re: String zerlegen; Trenner
 
Wo wir schon dabei sind: Warum machst du das eigentlich nicht? Eine einfache while-Schleife mit einem PosEx-Aufruf im Innern sollte dafür doch ausreichen...

quendolineDD 23. Okt 2007 16:47

Re: String zerlegen; Trenner
 
Delphi-Quellcode:
function cuttext(AString: string; delimiter: Char):array of string
var i: integer;
begin
setlength(result, 0);
i := 0;
while (pos(delimiter, astring) <> 0)then
 begin
    setlength(result, i+1);
    result[i] := copy(astring, 0, pos(delimiter, astring)-1);
    delete(astring, 1, pos(delimiter, astring));
    inc(i);
 end;
end;
Das dürfte doch deinem gewünschten sehr nahe kommen ;)
Code ungetestet, habe den nur schnell hier geschrieben!

EDIT:

Habe die Boolean rausgenommen, ich glaub die Abfrage nach dem Trennzeichen düfte genügen

Neutral General 23. Okt 2007 16:50

Re: String zerlegen; Trenner
 
Hi,

Hab mal was gebaut. Hab mich bisschen an der VCL Orientiert aber passt schon ;)

Delphi-Quellcode:
interface

uses ...;

type
  TStringlist = class(Classes.TStringlist)
  private
    FDelText: String;
    procedure SetDelimitedText(const Value: String);
  public
    property DelimitedText: String read FDelText write SetDelimitedText;
  end;

implementation

procedure TStringlist.SetDelimitedText(const Value: String);
var P,tmp: PChar;
    S: String;
begin
  FDelText := Value;
  BeginUpdate;
    Clear;
    P := PChar(Value);
    while P^ <> #0 do
    begin
      tmp := P;
      while (P^ >= ' ') and (P^ <> Delimiter) do // >= ist wichtig.. Im Original ists nur >
        inc(p);
      SetString(S,tmp,P-tmp);
      Add(S);
      inc(p);
    end;
  EndUpdate;
end;

// Anwendung

procedure TForm1.Button1Click(Sender: TObject);
var S: TStringlist;
begin
  S := TStringlist.Create;
  try
    S.Delimiter := ';';
    S.DelimitedText := 'Ich;schreibe was;hier hin;!!!';
    Memo1.Text := S.Text;
  finally
    S.Free;
  end;
end;
Gruß
Neutral General

KPBecker 23. Okt 2007 16:55

Re: String zerlegen; Trenner
 
Vielen Dank an die Helfer,

Ähnliches habe ich in einem anderen Programm, als ich von 'delimitedText' noch nichts wußte, auch schon als Lösung geschrieben.
Ich hoffte, daß eine eingebaute Funktion eine einfache Möglichkeit wäre.

Klaus-Peter

KPBecker 23. Okt 2007 17:00

Re: String zerlegen; Trenner
 
Den Vorschlag des neutralen Generals werde ich mir auch noch einmal unter dem Aspekt "praktisches Beispiel für Modifikation einer Funktion" anschauen.

3_of_8 23. Okt 2007 17:03

Re: String zerlegen; Trenner
 
Wir haben doch jede Menge solcher Funktionen in der CL...

Eine einfache Suche hätte genügt.

shmia 23. Okt 2007 17:07

Re: String zerlegen; Trenner
 
Wenn man eine wasserdichte Lösung braucht, um CSV-Dateien zu lesen:
CSV Hilfsfunktionen
Damit darf dann auch das Trennzeichen in den Nutzdaten enthalten sein.

KPBecker 23. Okt 2007 17:10

Re: String zerlegen; Trenner
 
Hallo, Manuel,

die Frage war ja gerade nicht, wie oft schon jemand solche Funktionen selbst geschrieben hat. Das habe ich bei der Suche gesehen.

Die Frage war nach einer Delphi-eigenen Funktion (die aber auch funktionieren sollte).

Klaus-Peter

KrasserChecker 23. Okt 2007 17:14

Re: String zerlegen; Trenner
 
Ich frage mich ja, warum immer alles so umständlich sein muß :gruebel:
Es geht doch nur darum, einen Text der an allen Vorkommen von ; aufzutrennen.
Da die Stringliste hier ja tatsächlich nicht so recht mit "DelimitedText" funktioniert machen wir es doch einfach(!) selbst:
Delphi-Quellcode:
procedure SplitString(iTextToSplit: string; iDelimiter: Char; ioSL: TStrings);
begin
  ioSL.Clear;

  ioSL.Text := StringReplace(iTextToSplit, iDelimiter, sLineBreak, [rfReplaceAll]);
end;

marabu 23. Okt 2007 17:40

Re: String zerlegen; Trenner
 
Hallo Klaus-Peter,

lies dir mal die Online-Hilfe zur Eigenschaft StrictDelimiter durch - das könnte deinen Vorstellungen entsprechen.

Grüße vom marabu

Muetze1 23. Okt 2007 18:11

Re: String zerlegen; Trenner
 
Zitat:

Zitat von Phoenix
Aber das geht glaub ich erst seit Delphi 5.

Nur der Vollständigkeit halber: ab Delphi 6 verfügbar. Delphi 5's TStringList hatte keine DelimitedText oder Delimiter Eigenschaft.

Ralf Kaiser 23. Okt 2007 18:29

Re: String zerlegen; Trenner
 
Zitat:

Zitat von KPBecker
Als Trenner habe ich '|' gesetzt, aber das Blank wird auch als (zusätzlicher) Trenner interpretiert.
(It's not a bug, it's a feature ???)

Es ist wirklich ein Feature!

Ab D2006 gibt es ein zusätzliches Property in TStringList: "StrictDelimiter: boolean".

Wenn das true ist wurd nur noch der Delimiter als Trenner benutzt, ansonsten zählen auch Whitespaces als Trenner.

Voreinstellung ist dabei false, so verhält sich die TStringList so wie es vor D2006 immer üblich war (also Zeilenvorschübe und Whitspaces als zusätzliche Trenner)

Ciao,
Ralf

Edit: Oops, zweite Seite des Threads nicht gesehen, da wird ja schon von StrictDelimiter gesprochen, sorry.

Muetze1 23. Okt 2007 23:20

Re: String zerlegen; Trenner
 
Naja, eher wurde ein damaliger Bug mit einer neuen Eigenschaft abwärtskompatibel gefixt.

OldGrumpy 24. Okt 2007 07:08

Re: String zerlegen; Trenner
 
Zitat:

Zitat von KPBecker
Die Frage war nach einer Delphi-eigenen Funktion (die aber auch funktionieren sollte).

Die Antwort von marabu ist wohl ziemlich untergegangen, die Stringlist funktioniert sehr wohl, nur sind die Defaultwerte für manche Eigenschaften sehr unglücklich gewählt. So ist zum Beispiel StrictDelimiter standardmäßig auf False gesetzt, was zu unerwarteten Ergebnissen führt:

Zitat:

Zitat von Delphi Hilfe
Use this property to specify whether the Delimiter is the only value used within the DelimitedText property. If set to True, individual strings in DelimitedText are separated only by the character that is the value of Delimiter. If set to False, individual strings in DelimitedText can be separated by a space, a non-printable character, or the character that is the value of Delimiter.

EDIT: Da war ich wohl etwas langsam *gähn* Noch viel zu früh und der Kaffee wirkt auch noch nicht ;)

SirThornberry 24. Okt 2007 08:39

Re: String zerlegen; Trenner
 
Zitat:

Zitat von KrasserChecker
Ich frage mich ja, warum immer alles so umständlich sein muß :gruebel:
Es geht doch nur darum, einen Text der an allen Vorkommen von ; aufzutrennen.
Da die Stringliste hier ja tatsächlich nicht so recht mit "DelimitedText" funktioniert machen wir es doch einfach(!) selbst:
Delphi-Quellcode:
procedure SplitString(iTextToSplit: string; iDelimiter: Char; ioSL: TStrings);
begin
  ioSL.Clear;

  ioSL.Text := StringReplace(iTextToSplit, iDelimiter, sLineBreak, [rfReplaceAll]);
end;

warum so kompliziert - ganz einfach. Weil deine Funktion fehlerhafte Ergebnisse liefert :-D
Hab ich folgenden Text
Zitat:

Überschrift1

Text1
##
Überschrift2

Text2
so würden bei deinem Beispiel Überschrift1 und Text1 nicht mehr zusammen sein weil auch die #13#10 wie üblich interpretiert werden.
Bei dir hätte die Stringlist dann also 6 oder 7 einträge und nicht 2 wie gewünscht (für jeden Abschnitt einen Stringlist eintrag)

Luckie 24. Okt 2007 09:13

Re: String zerlegen; Trenner
 
Auf Matze scheint irgendwie niemand zu hören-. Also hier noch mal: Explode

Warum nicht auf bewährtes zurückgreifen?

3_of_8 24. Okt 2007 11:29

Re: String zerlegen; Trenner
 
Du meinst wohl eher auf mich?

Luckie 24. Okt 2007 11:36

Re: String zerlegen; Trenner
 
Zitat:

Zitat von 3_of_8
Du meinst wohl eher auf mich?

Ups. :duck:

KPBecker 24. Okt 2007 16:04

Re: String zerlegen; Trenner
 
Hallo, Delphi-Praktiker,

marabu und Ralf haben die Lösung (für mein Problem) genannt:
Den 'StrictDelimiter' hatte ich übersehen.

Daß man in ähnliche Probleme noch deutlich mehr Aufwand stecken kann, ist unbenommen. Ein schönes Beispiel wurde von shmia genannt: Delimiter, die in eingerahmtem ("...") Text enthalten sind, dort aber nicht als Trenner gelten sollen. ...

Vielen Dank,
Klaus-Peter


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:24 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz