![]() |
Delphi-Version: 10.2 Tokyo
Effiziente Methode, einen String mittels Delimiter zu splitten
Hallo!
Ich kenne mittlerweile ein halbes Dutzend Methoden, einen String anhand eines Delimiter zu splitten. Die meisten arbeiten mit TStringList. Entweder mit DelimitedText, was aber den Nachteil hat dass man nur ein Zeichen (Char) als Delimiter einsetzen kann. Oder mittels
Delphi-Quellcode:
Teilweise habe ich auch schon gesehen, den String mit einer Runner-Schleife zu durchlaufen, Memcopy je Zeichen in einen zweiten String zu machen und beim Auffinden eines Delimiter den zweiten String in eine Stringliste zu adden. Davon gibt es auch noch eine Variante, einen String als PChar anzusprechen, den Zeiger zu schubsen, Memcopy direkt auf StringList.Text zu machen und gefundene Delimiter durch sLineBreak zu ersetzen.
SL.Text:= StringReplace(TheString, TheDelimiter, sLineBreak, [rfReplaceAll]);
Nur frage ich mich, wie effizient ist denn diese ganze "Schleiferei"? Die meisten dieser Codeschnipsel sind 10 Jahre und älter. Gibt es vielleicht inzwischen in der RTL mitgeliefert schon eine Art Äquivalent zu der explode()-Funktion in PHP, die z.B. ein TStringDynArray auswirft? Grüße Cody EDIT: PS: Schön wäre die Möglichkeit, als Delimiter mehr als ein Zeichen (Char) verwenden zu können. |
AW: Effiziente Methode, einen String mittels Delimiter zu splitten
Suchst du sowas?
Delphi-Quellcode:
function Explode(const ADelimiter, AString: string): TArray<string>;
begin Result := AString.Split([ADelimiter]); end; StrOut := Explode(':;', StrIn); |
AW: Effiziente Methode, einen String mittels Delimiter zu splitten
In den neueren Versionen gibt es s.Split (s ist ein String).
|
AW: Effiziente Methode, einen String mittels Delimiter zu splitten
Ha, dacht ichs mir doch dass es inzwischen was generisches ab Werk gibt :-) Und dann auch noch so schön flexibel. Schade nur dass
![]() |
AW: Effiziente Methode, einen String mittels Delimiter zu splitten
Die Funktion SplitString gibt es in StrUtils schon seit D2010.
|
AW: Effiziente Methode, einen String mittels Delimiter zu splitten
Ich schätze mal dass dies einer dieser Fälle ist, wo das Internet voll ist mit wieder und wieder kopierten und modifizierten Varianten, die aus grauer Ansistring-Vorzeit stammen. Lässt man nämlich - mangels Kenntnis dessen - das Keyword "Split" weg oder verwendet stattdessen "explode" als Suchbegriff, findet man nur die altertümlichen Schleifenlösungen.
|
AW: Effiziente Methode, einen String mittels Delimiter zu splitten
Zitat:
Zumindest nicht in dem Sinn wie "generisch" in Delphi bzw. generell in Programmiersprachen benutzt wird. |
AW: Effiziente Methode, einen String mittels Delimiter zu splitten
Der Ergebnistyp ist generisch :-) Mehr meinte ich damit eigentlich gar nicht.
|
AW: Effiziente Methode, einen String mittels Delimiter zu splitten
Hier ein Mini Beispiel wie man es machen könnte:
Delphi-Quellcode:
Meintest Du so etwas?
procedure MySplit (const Delimiter: Char; Input: string; const Strings: TStrings);
begin Assert(Assigned(Strings)); Strings.Clear; Strings.Delimiter := Delimiter; Strings.DelimitedText := Input; end; // Aufruf: procedure TForm1.Button1Click(Sender: TObject); var SL: TStringList; begin SL := TStringList.Create; try MySplit(' ', 'Hallo Delphi Praxis', SL); ShowMessage(SL[0]); // = Hallo ShowMessage(SL[1]); // = Delphi ShowMessage(SL[2]); // = Praxis finally SL.Free; end; end; |
AW: Effiziente Methode, einen String mittels Delimiter zu splitten
Du hast den Eingangsbeitrag gelesen?
Zitat:
|
AW: Effiziente Methode, einen String mittels Delimiter zu splitten
Ich war gerade auch auf der Suche danach, einen String zu splitten und einen Rückgabewert zu erhalten (für eine bestimmte Position im String), mittels einer Standard-Funktion in Delphi, um nicht immer direkt meine eigenen Units einbinden zu müssen, wenn man mal nur einen kleinen Demo-source zeigen möchte.
SplitString hatte ich dann in StrUtils gefunden, aber hier im Forum nochmal interessehalber mal nach "Splitstring" gesucht. Und siehe da, String.Split ist natürlich noch viel schöner und außerdem schon in System.Sysutils drin, die automatisch eingebunden wird, wenn man eine neue Form anlegt. Damit kann man das elegant so machen:
Delphi-Quellcode:
Etwas schade ist zwar, dass ein dynamisches Array für alle Teilstrings erzeugt wird, da ich eigentlich nur einen Eintrag brauche, aber wie gesagt, brauche keine extra Unit und wenn es nicht auf Performance ankommt, bzw. ein Demo zu gestalten, ohne Drittfunktionen zu brauchen, dann geht das schon mal so.
procedure TF_Main.Button1Click(Sender: TObject);
var s, Part: string; begin s := '#Müller#Hans#Bonn'; // bisher "GetFieldStr" aus meiner eigenen Unit // ShowMessage (GetFieldStr ('#', S, 2); // Müller, Zähung 1-basiert ShowMessage (Splitstring (S, '#')[1]); //Müller, Zählung 0-basiert // Noch kürzer geht es so ShowMessage (S.Split(['#'])[3]); // Bonn end; |
AW: Effiziente Methode, einen String mittels Delimiter zu splitten
Zitat:
|
AW: Effiziente Methode, einen String mittels Delimiter zu splitten
Und natürlich geht ohne Prüfung vor Zugriff sowas nicht, wenn es zu wenige Teilstrings gibt.
Aber hier könnte man auch einfach dafür sorgen, dass die Anzahl immer stimmt.
Delphi-Quellcode:
ShowMessage((S + '###').Split(['#'])[3]);
"Effizient" meint hier also schöner "kurzer" Code und wenige/keine externen Abhängigkeiten? |
AW: Effiziente Methode, einen String mittels Delimiter zu splitten
Zitat:
|
AW: Effiziente Methode, einen String mittels Delimiter zu splitten
Zitat:
Wenn ich ein lauffähiges Beispiel liefern möchte, für das der Anwender mit den Delphi-Standard-Units auskommen soll, dann wäre s.split also ein Ersatz für das, was ich sonst verwende (meine sonst verwendete GetFieldStr-Funktion hat natürlich verschiedene Absicherungen und liefert auch das richtige zurück, wenn weniger Felder als vermutet da). Aber ansonsten: Natürlich kann ich auf Prüfung vor Zugriff verzichten, wenn ich definitiv weiß, dass der String mindestens die angeforderte Anzahl von Teilstrings enthält. |
AW: Effiziente Methode, einen String mittels Delimiter zu splitten
So dumm ist das gar nicht :-) Bisher habe ich das immer mit Stringlisten gelöst und nach dem Splitten mit if Count >= Mindestanzahl geprüft.
Andererseits ist das auch wieder fallabhängig. Denn durch das Sicherstellen von einer Mindestanzahl nimmt man sich unter Umständen die Möglichkeit, Eingabefehler zu prüfen. Kommt also immer auf den konkreten Einsatzzweck an. |
AW: Effiziente Methode, einen String mittels Delimiter zu splitten
Zitat:
Lange Antwort: Lineare Ausdrücke korrekt zu erstellen ist ein großer Aufwand, wenn man sowas nicht täglich macht. Es reicht, wenn man es ein-/zweimal falsch macht und nach dem Fehler sucht, um jeglichen Vorteil aufzuwiegen. ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz