Entwickler-Ecke

Sonstiges (Delphi) - String zerteilen


Zaubär - Mo 23.12.02 22:04
Titel: String zerteilen
Hi Leute,

kennt jemand eine elegante Lösung einen String, der im folgenden Stil aufgebaut ist zu zerteilen:


Quelltext
1:
'Einleitung','Startbemerkung', '235','Schlussbemerkung'                    

Schlussendlich sollte ich dann in meinen Variablen folgendes Ergebnis haben:

Quelltext
1:
2:
3:
4:
Variable 1 = 'Einleitung'
Variable 2 = 'Startbemerkung'
Variable 3 = '235'
Variable 4 = 'Schlussbemerkung'

Bisher hab ich's mit dem Befehl Pos() und ein paar Schlaufen geschafft. Allerdings finde ich meine jetzige Variante sehr umständlich...


Visum - Di 24.12.02 13:49

Hi,
du könntest es mit dem Kommatext einer Stringliste versuchen.

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.Button1Click(Sender: TObject);
var Liste:tstringlist;
begin
Liste:=tstringlist.create;
Liste.CommaText:=edit1.text;
showmessage(Liste[0]);
showmessage(Liste[1]);
end;


Dadurch wird der String an jedem Komma getrennt in ein Feld der Stringlist geschrieben. Darauf kannst du wie bei einem array zugreifen, angefangen bei 0.

mfG und frohe Weihnachten
Visum


Zaubär - Di 24.12.02 15:15

Das funktioniert leider nicht. Ich hab es vielleicht schlecht erwähnt, aber das Trennzeichen ist nicht immer ein Komma, sondern 2 Leerschläge ein Kästchen und dann nochmal zwei Leerschläge.


Wolff68 - Di 24.12.02 17:03

Zaubär hat folgendes geschrieben:
Das funktioniert leider nicht. Ich hab es vielleicht schlecht erwähnt, aber das Trennzeichen ist nicht immer ein Komma

Also Liste.CommaText ist ja nur eine Sonderform von Liste.DelimitedText
Das heist, Du kannst durchaus das Trennzeichen selber angeben.
Diese Funktion hat nur den Nachteil, daß sowohl das Trennzeichen als auch die Textbegrenzungen nur 1 Char sein dürfen und im sonstigen Text nicht vorkommen sollten.

Sowas wie 'Einleitung' / 'Startbemerkung'/ '235'/'Schlussbemerkung' funktioniert mit / als .Delimiter und ' als .QuoteChar ganz gut.
Sowas wie 'Einleitung' #/# 'Startbemerkung' #/# '235' #/# 'Schlussbemerkung' funktioniert dagegen nicht so gut.

Ist die Frage, ob Du das jetzige Trennzeichen Funktionskonform ändern kannst, oder was genau Du denn als Trennzeichen hast. (Vielleicht mal das Posten, was wirklich zerlegt werden soll ?)


Wolff68 - Di 24.12.02 17:16

Mir fällt grad noch was ein:

Du könntest auch vorher mit StringReplace den String 'vorbehandeln'.
Vorteil: Bei StringReplace kannst Du ganze Zeichenfolgen ersetzen. 8)


Quelltext
1:
2:
3:
4:
5:
s := 'Einleitung  /  Startbemerkung 1  /  235  /  Schlussbemerkung';
s := '#'+StringReplace(s,'  /  ','#/#',[rfReplaceAll])+'#';
List.Delimiter := '/';
List.QuoteChar := '#';
List.DelimitedText := s;
ungetestet
# und / kannst natürlich auch durch anderes ersetzen. Sogar sowas wie Chr(10) und Chr(13) sollte da funktionieren.


Zaubär - Di 24.12.02 17:21

Also, ich hab mehrere hundert Möglichkeiten und eine hab ich mal hier eingefügt. Der String sieht so aus:

Quelltext
1:
2:
3:
ID3    NTRCK      15TENC   @  Franz BeispielWXXX       www.keine-ahnung.deTCOP      2002TOPE      224TCOM      1111COMM          Nicht ganz typisch!TCON        (17)RockTYER      1975TALB   
   High VoltageTPE1      AC DCTIT2   
   Love Song



Und das sollte dann dabei rauskommen:
Love Song
AC DC
High Voltage
15
1975
Rock
Nicht ganz typisch!
1111
224
2002
http://www.keine-ahnung.de
Franz Beispiel


bis11 - Di 24.12.02 17:48

Hi,

Zitat:

Code:
ID3 NTRCK  15TENC @ Franz BeispielWXXX  http://www.keine-ahnung.deTCOP  2002TOPE  224TCOM  1111COMM  Nicht ganz typisch!TCON (17)RockTYER  1975TALB
High VoltageTPE1  AC DCTIT2
Love Song


Diese rechtecke oder schwarzen Striche sind CR-Zeichen. Wenn Du diese Datei mal mit einem anderen Editor öffnest, werden Dir alle Sachen untereinander angezeigt.

Frohe Weihnachten.


Zaubär - Di 24.12.02 19:51

Das heisst als, der String wird mir automatisch geteilt??


Delete - Di 24.12.02 20:51

@bis11: Das müssen nicht zwangsläufig Zeilenumbrüche sein. Das kommt auf´s Dateiformat an.

@Zaubär: Wenn es Zeilenumbrüche sind, dann passiert beim Laden der Datei in einem Editor das, was bis11 angesprochen hat. Die einzelnen Zeilen werden untereinander dargestellt, so dass du theoretisch jede Zeile einzeln lesen und auswerten kannst.

@Wolf: StringReplace ist furchtbar langsam. Vielleicht erinnerst du dich noch an den Thread zum Thema Verschlüsselung, an dem sich du, ich und Peter (Lustig) beteiligten. Sollte hier noch zu finden sein. Du hast dort ebenfalls eine StringReplace-Lösung gepostet. In der Geschwindigkeit musste sich diese Version allerdings den Lösungen von Peter und mir geschlagen geben. In dem Fall mag´s vielleicht gehen, aber je länger der Input-String, desto länger dauert die Umwandlung.

Ich persönlich glaube, dass Zaubär irgendein binäres Format auslesen will. Dann würde ich sowieso anders herangehen. Aber darüber Gedanken machen und äußern lohnt nicht, solange man nicht weiß, was Zaubär auslesen will.


Zaubär - Di 24.12.02 23:18

OK, mit den genannten Wörtern, die ich euch spendiert habe, dachte ich es wäre klar.
Doch nun die vollständige Erklärung. Bei diesem String handelt es sich um den ID3v2 Tag einer MP3-Datei, und der ist genauso im Text-format in der Datei abgespeichert.
Da ich keinen Algorithmus hierfür gefunden habe möchte ich es nun auf eigene Faust probieren...


Delete - Mi 25.12.02 00:54

Den Tag mußt du binär auslesen. Infos zum Dateiformat fidest du unter http://www.wotsit.org .


Zaubär - So 29.12.02 22:47

Luckie hat folgendes geschrieben:
Den Tag mußt du binär auslesen

Und kannst du mir auch einen kleinen Tipp verraten, wie ich das am besten anstellen soll ??


Dev4u.ch - Mo 30.12.02 00:33

http://www.swissdelphicenter.ch/de/showcode.php?id=121

gruss


Anonymous - Mo 30.12.02 08:12

Hier Popov's vielfach prämierte Routine von zum zerteilen von Strings:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
function DelimiterToCommaText(Text: String; Del: String): String;
var Sl: TStringList;
begin
  Sl := TStringList.Create;
  try while Length(Trim(Text)) <> 0 do begin
      if Pos(Del, Text) = 0 then Text := Text + Del;
      Sl.Add(Trim(Copy(Text, 1, Pos(Del, Text) - 1)));
      Delete(Text, 1, Pos(Del, Text) + Length(Del) - 1);
    end;
    Result := Sl.CommaText;
  finally Sl.Free end;
end; {Popov}

procedure TForm1.Button1Click(Sender: TObject);
var
  Text, Del: String;
begin
  Text := '254#*-#24#*-#250#*-#138#*-#186#*-#162#*-#190#*-#128';
  Del := '#*-#';
  ListBox1.Items.CommaText := DelimitedToCommaText(Text, Del);;
end;


Warum nicht gleich StringReplace? Weil nicht jedes Delphi StringReplace hat.


Zaubär - Mo 30.12.02 09:04

Danke schön!
PS: Ich hab nur Delphi 4 Standart, Delphi 5 Prof. & Delphi 6 Enterprise


Zaubär - Mo 30.12.02 09:06

@dev4u.ch: Dein Code Beispiel bringt mich leider nicht weiter. Das ist nämlich der ID3Tag Version 1, welchen ich schon lange funktionstüchtig in mein Programm eingabaut haben. Das was ich noch hinzufügen will ist der ID3Tag Version 2! Und der ist am Dateianfang und etwas schwieriger zu behandeln.


bis11 - Mo 30.12.02 09:09

Hast Du schon mal Dir die Seite angesehen, die Dir Luckie geschrieben hat. Denn auf dieser Seite findest Du Anleitung so wie Komponenten dazu um den ID3Tag v2 auszulesen. Oder Du suchst in der Sparte Freeware-Projekte hier im Forum nach MP3Renamer. Denn dieses Programm kann den ID3Tag v2 auslesen und ändern, sprich mal mit dem Autor, vielleicht gibt der Dir ja noch einen Tip oder ein Beispiel.