Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Herauslösen eines Strings im string (https://www.delphipraxis.net/179344-herausloesen-eines-strings-im-string.html)

Ajintaro 28. Feb 2014 11:03

Herauslösen eines Strings im string
 
Hallo liebe DP !

Ich hab einige "Datensätze" in einer Textdatei abgelegt in diesem Format:

Code:
ID,[HEADLINE],TEXT1=TEXT2
sieht dann so aus:
Code:
12345,[WASSER],Wasser ist, wie es ist=Muss geschützt werden, oder?
Diese Datensätze werden zeilenweise in eine Listbox eingelesen. Wenn ich nun einen Eintrag selektiere, möchte ich einen Datensatz in seine Bestandteile zerlegen. Das hab ich so erledigt:

Delphi-Quellcode:
procedure TForm1.ListBox2Click(Sender: TObject);
var s_1,s_2,s_3, s_4:string;
ipos, yPos, x1pos, x2Pos:integer;
begin
 
 //Allen 4 Strings den selbe Zeile zuweisen
 s_1 := ListBox2.Items[ListBox2.ItemIndex];
 s_2 := ListBox2.Items[ListBox2.ItemIndex];
 s_3 := ListBox2.Items[ListBox2.ItemIndex];
 s_4 := ListBox2.Items[ListBox2.ItemIndex];

 //String1 = ID herauslösen
 yPos := Pos (',', s_1);//erstes Komma finden
 if (yPos > 0) then
 begin
   //Komma gefunden
   Delete(s_1,ypos, s_1.Length-1);
   Delete(s_2,1, yPos);
   e_id.Text:=s_1;
 end;

  //String HEADLINE herauslösen
  x1Pos := Pos ('[', s_4);
 if (x1Pos > 0) then
 begin
   //erste Klammer gefunden, jetzt 2. Klammer suchen
    x2Pos := Pos (']', s_4);
    if (x2Pos > 0) then
    begin
      //jetzt zurechtschneiden
       Delete(s_4,1, x1Pos);
       Delete(s_4,x2Pos,s_4.Length-1);
       showmessage(s_4);
    end;
 end;

 //STRING TEXT1
....
End;
Das funktioniert mit der ID problemlos, allerdings kann ich den Text zwischen den [ ] nicht richtig herauslösen, ich bekomme immer noch 3 Zeichen zusätzlich angezeigt. Aus
Code:
ID,[HEADLINE],TEXT1=TEXT2
soll
Code:
HEADLINE
werden, ist aber
Code:
HEADLINE],TE
Komischerweise ist
Delphi-Quellcode:
Delete(s_4,1, x1Pos);
völlig korrekt und schneidet alles bis zur ersten [ ab.
AUch
Delphi-Quellcode:
Delete(s_4,x2Pos,s_4.Length-1);
schneidet alles ab ].

Beides zusammen:
Delphi-Quellcode:
Delete(s_4,1, x1Pos);
Delete(s_4,x2Pos,s_4.Length-1);
showmessage(s_4);
bringt ein falsches Ergebnis.. :?:

DeddyH 28. Feb 2014 11:05

AW: Herauslösen eines Strings im string
 
Durch das erste Delete ändert sich die Stringlänge, deshalb passt der 2. Index nicht mehr. Benutz doch statt 2 * Delete 1 * Copy, dann hast Du das Problem nicht.

[edit] Alternativ kannst Du auch beim Delete bleiben, darfst dann aber x2Pos erst nach dem ersten Löschen ermitteln. [/edit]

p80286 28. Feb 2014 11:15

AW: Herauslösen eines Strings im string
 
oder wie man es bei Löschungen meist machen sollte, von hinten nach vorne
Delphi-Quellcode:
Delete(s_4,x2Pos,s_4.Length-1);
Delete(s_4,1, x1Pos);
showmessage(s_4);
Gruß
K-H

sx2008 28. Feb 2014 11:44

AW: Herauslösen eines Strings im string
 
Anstatt immer nur mit
Delphi-Quellcode:
Pos()
und
Delphi-Quellcode:
Delete()
zu arbeiten würde ich besser eine Funktion einsetzen die spezieller auf die Aufgabe zugeschnitten ist:
Delphi-Quellcode:
function StrToken(var S: string; Separator: Char): string; // kopiert aus der JCL
var
  I: Integer;
begin
  I := Pos(Separator, S);
  if I <> 0 then
  begin
    Result := Copy(S, 1, I - 1);
    Delete(S, 1, I);
  end
  else
  begin
    Result := S;
    S := '';
  end;
end;
Und dann:
Delphi-Quellcode:
  s := ListBox2.Items[ListBox2.ItemIndex];
  s_1 := StrToken(s, ','); // ID abtrennen
  s_2 := StrToken(s, ','); // Headline abtrennen
Dieser Code ist wesentlich besser zu verstehen als die ganze Serie von Delete, Pos und Length.
Sollte in Zukunft ein ähnliches Problem anstehen, dann hast du gleich eine Funktion um es zu lösen.

Popov 28. Feb 2014 15:17

AW: Herauslösen eines Strings im string
 
Warum zerlegst du es erst wenn das angeklickt wird, wieso hängst du nicht gleich einen Datensatz an das Item und liest dann bequem die Infos aus dem Datensatz?
Delphi-Quellcode:
Type
  TDatensatz = class
    ID: String; //oder Integer
    HEADLINE: String;
    TEXT1: String;
    TEXT2: String;
  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  s: String;
  Datensatz: TDatensatz;
begin
  s := '12345,[WASSER],Wasser ist, wie es ist=Muss geschützt werden, oder?';

  Datensatz := TDatensatz.Create;
  Datensatz.ID := '12345';
  Datensatz.HEADLINE := 'WASSER';
  Datensatz.TEXT1 := 'Wasser ist, wie es ist';
  Datensatz.TEXT2 := 'Muss geschützt werden, oder?';

  with ListBox2 do Items.AddObject(s, Datensatz);
end;

procedure TForm1.ListBox2Click(Sender: TObject);
var
  s: String;
  Datensatz: TDatensatz;
begin
  with ListBox2 do if ItemIndex < 0 then Exit;

  with ListBox2 do s := Items[ItemIndex];
  with ListBox2 do Datensatz := TDatensatz(Items.Objects[ItemIndex]);

  ShowMessage(
   'Item-String: ' + s + #13#10 +
   'ID: ' + Datensatz.ID + #13#10 +
   'HEADLINE: ' + Datensatz.HEADLINE + #13#10 +
   'TEXT1: ' + Datensatz.TEXT1 + #13#10 +
   'TEXT2: ' + Datensatz.TEXT2
    );
end;
Evtl. mußt du vorher noch OwnsObjects auf True setzten. Bei Delphi 7 geht das nicht, bei deiner Version sollten die Eigenschaft vorhanden sein. Wenn OwnsObjects auf True ist, mußt du die Objekte beim Löschen der Items nicht vorher freigeben.

DeddyH 28. Feb 2014 15:23

AW: Herauslösen eines Strings im string
 
Wenn die "Datensätze" aus einer Textdatei kommen, müssen sie doch trotzdem geparst werden. Von daher erschließt sich mir der Nutzen nicht so richtig.

Ajintaro 28. Feb 2014 15:39

AW: Herauslösen eines Strings im string
 
Hallo ihr lieben,

Ich habe etwas weiter experimentiert und dabei eure Vorschläge berücksichtigt. Zunächst hat DeddyH den Fehler in meines codes erkannt, der 2. index wird um die Zeichen verschoben, welche ich vorher entferne :thumb:

Die Funktionslösung von sx2008 hat mir auch sehr gut gefallen, das ist in der Tat besser als meine Delete-Serie. Allerdings bekomm ich dann ein Problem, wenn der Datensatz keine [HEADLINE] hat. Dann stürzt sich die Funktion auf das nächste Komma, nämlich auf den Satzzeichen und zerpflückt den Text:
Code:
Wasser ist, wie es ist
in
Code:
wie es ist
Es kommt dann zum selben Problem wie in meiner Lösung: der Index passt nicht mehr.

Den Ansatz von Popov muss ich noch testen. Da die Listbox von einer Datei mit 400 Zeilen gespeist wird, müsste ich zunächst Zeile für Zeile:
Code:
'12345,[WASSER],Wasser ist, wie es ist=Muss geschützt werden, oder?'
als
Delphi-Quellcode:
Datensatz: TDatensatz;
einlesen.

Popov 28. Feb 2014 15:56

AW: Herauslösen eines Strings im string
 
@DeddyH

Wird nicht allgemein behauptet, dass man Daten und Darstellung trennen sollte?

@Ajintaro

Würdest du die Daten in der Form speichern:
Code:
"ID","[HEADLINE]","TEXT1","TEXT2"
könntest du die Zeile in ein TStrings, bzw. TStringList als CommaText einlesen. Das Ergebnis wäre z. B. eine TStrigList mit vier Zeilen, von denen jede eine Info enthalten würde. In dem Fall würde das System für dich die Zeile trennen.

DeddyH 28. Feb 2014 15:59

AW: Herauslösen eines Strings im string
 
Zitat:

Zitat von Popov (Beitrag 1250046)
@DeddyH

Wird nicht allgemein behauptet, dass man Daten und Darstellung trennen sollte?

Und was hat das mit Deinem Code zu tun? Der müsste auch erst parsen, oder sollen überall dieselben konstanten Strings benutzt werden? Und wenn schon eine Klasse, dann aber bitte mit Properties, wie es sich gehört.

Popov 28. Feb 2014 16:04

AW: Herauslösen eines Strings im string
 
Wo steht das, dass Properties sein müssen?

Sicher, man kann das schöner und besser machen, aber für diese Aufgabe reicht es.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:06 Uhr.
Seite 1 von 3  1 23      

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