Teilen Sie einen String in ein Array von Strings, basierend auf einem Delimiter

Ich versuche, eine Delphi-function zu finden, die eine Eingabezeichenfolge in ein Array von Zeichenfolgen basierend auf einem Trennzeichen aufteilt. Ich habe eine Menge bei Google gefunden, aber alle scheinen ihre eigenen Probleme zu haben und ich konnte keine von ihnen zur Arbeit bringen.

Ich muss nur eine Zeichenfolge wie "word:doc,txt,docx" in ein Array basierend auf “:” "word:doc,txt,docx" . Das Ergebnis wäre ['word', 'doc,txt,docx'] .

Hat jemand eine function, von der sie wissen, dass sie funktioniert?

Vielen Dank

   

    Sie können die Eigenschaft TStrings.DelimitedText verwenden, um eine Zeichenfolge zu teilen

    Überprüfen Sie dieses Beispiel

     program Project28; {$APPTYPE CONSOLE} uses Classes, SysUtils; procedure Split(Delimiter: Char; Str: string; ListOfStrings: TStrings) ; begin ListOfStrings.Clear; ListOfStrings.Delimiter := Delimiter; ListOfStrings.StrictDelimiter := True; // Requires D2006 or newer. ListOfStrings.DelimitedText := Str; end; var OutPutList: TStringList; begin OutPutList := TStringList.Create; try Split(':', 'word:doc,txt,docx', OutPutList) ; Writeln(OutPutList.Text); Readln; finally OutPutList.Free; end; end. 

    AKTUALISIEREN

    Siehe diesen Link für eine Erklärung von StrictDelimiter .

    Es besteht keine Notwendigkeit, eine Split function zu entwickeln. Es existiert bereits, siehe: Classes.ExtractStrings .

    Benutze es auf folgende Weise:

     program Project1; {$APPTYPE CONSOLE} uses Classes; var List: TStrings; begin List := TStringList.Create; try ExtractStrings([':'], [], PChar('word:doc,txt,docx'), List); WriteLn(List.Text); ReadLn; finally List.Free; end; end. 

    Und um die Frage vollständig zu beantworten; List repräsentiert das gewünschte Array mit den Elementen:

     List[0] = 'word' List[1] = 'doc,txt,docx' 

    StrUtils.SplitString in Delphi 2010

    Verwenden der in Delphi XE3 eingeführten function SysUtils.TStringHelper.Split:

     var MyString: String; Splitted: TArray; begin MyString := 'word:doc,txt,docx'; Splitted := MyString.Split([':']); end. 

    Dies teilt eine Zeichenfolge mit einem gegebenen Begrenzer in ein Array von Zeichenfolgen auf.

    Ähnlich wie die function Explode () , die von Mef angeboten wird, aber mit ein paar Unterschieden (von denen ich einen Bug-Fix halte):

      type TArrayOfString = array of String; function SplitString(const aSeparator, aString: String; aMax: Integer = 0): TArrayOfString; var i, strt, cnt: Integer; sepLen: Integer; procedure AddString(aEnd: Integer = -1); var endPos: Integer; begin if (aEnd = -1) then endPos := i else endPos := aEnd + 1; if (strt < endPos) then result[cnt] := Copy(aString, strt, endPos - strt) else result[cnt] := ''; Inc(cnt); end; begin if (aString = '') or (aMax < 0) then begin SetLength(result, 0); EXIT; end; if (aSeparator = '') then begin SetLength(result, 1); result[0] := aString; EXIT; end; sepLen := Length(aSeparator); SetLength(result, (Length(aString) div sepLen) + 1); i := 1; strt := i; cnt := 0; while (i <= (Length(aString)- sepLen + 1)) do begin if (aString[i] = aSeparator[1]) then if (Copy(aString, i, sepLen) = aSeparator) then begin AddString; if (cnt = aMax) then begin SetLength(result, cnt); EXIT; end; Inc(i, sepLen - 1); strt := i + 1; end; Inc(i); end; AddString(Length(aString)); SetLength(result, cnt); end; 

    Unterschiede:

    1. Der Parameter aMax begrenzt die Anzahl der zurückzugebenden Zeichenketten
    2. Wenn die Eingabezeichenfolge durch ein Trennzeichen beendet wird, wird angenommen, dass eine nominale "leere" letzte Zeichenfolge existiert

    Beispiele:

     SplitString(':', 'abc') returns : result[0] = abc SplitString(':', 'a:b:c:') returns : result[0] = a result[1] = b result[2] = c result[3] =  SplitString(':', 'a:b:c:', 2) returns: result[0] = a result[1] = b 

    Es ist das schließende Trennzeichen und das fiktive "leere letzte Element", das ich für den Bugfix halte.

    Ich habe auch die Änderung der Speicherzuweisung, die ich vorgeschlagen habe, mit Verfeinerungen eingebaut (ich habe irrtümlich vorgeschlagen, dass die Eingabezeichenfolge höchstens 50% Trennzeichen enthalten könnte, aber es könnte denkbar sein, dass sie aus 100% Trennzeichenfolgen besteht, was ein Array leerer Elemente ergibt!)

    Ich benutze immer etwas ähnliches:

     Uses StrUtils, Classes; Var Str, Delimiter : String; begin // Str is the input string, Delimiter is the delimiter With TStringList.Create Do try Text := ReplaceText(S,Delim,#13#10); // From here on and until "finally", your desired result strings are // in strings[0].. strings[Count-1) finally Free; //Clean everything up, and liberate your memory ;-) end; end; 

    Explode ist eine sehr schnelle function, die aus der TStrings-Komponente stammt. Ich verwende nächsten Test für explodieren: Explode 134217733 Bytes von Daten, ich bekomme 19173962 Elemente, Zeit der Arbeit: 2984 ms.

    Implode ist sehr niedrige Geschwindigkeit, aber ich schreibe es einfach.

     { ****************************************************************************** } { Explode/Implode (String <> String array) } { ****************************************************************************** } function Explode(S: String; Delimiter: Char): Strings; overload; var I, C: Integer; P, P1: PChar; begin SetLength(Result, 0); if Length(S) = 0 then Exit; P:=PChar(S+Delimiter); C:=0; while P^ <> #0 do begin P1:=P; while (P^ <> Delimiter) do P:=CharNext(P); Inc(C); while P^ in [#1..' '] do P:=CharNext(P); if P^ = Delimiter then begin repeat P:=CharNext(P); until not (P^ in [#1..' ']); end; end; SetLength(Result, C); P:=PChar(S+Delimiter); I:=-1; while P^ <> #0 do begin P1:=P; while (P^ <> Delimiter) do P:=CharNext(P); Inc(I); SetString(Result[I], P1, P-P1); while P^ in [#1..' '] do P:=CharNext(P); if P^ = Delimiter then begin repeat P:=CharNext(P); until not (P^ in [#1..' ']); end; end; end; function Explode(S: String; Delimiter: Char; Index: Integer): String; overload; var I: Integer; P, P1: PChar; begin if Length(S) = 0 then Exit; P:=PChar(S+Delimiter); I:=1; while P^ <> #0 do begin P1:=P; while (P^ <> Delimiter) do P:=CharNext(P); SetString(Result, P1, P-P1); if (I <> Index) then Inc(I) else begin SetString(Result, P1, P-P1); Exit; end; while P^ in [#1..' '] do P:=CharNext(P); if P^ = Delimiter then begin repeat P:=CharNext(P); until not (P^ in [#1..' ']); end; end; end; function Implode(S: Strings; Delimiter: Char): String; var iCount: Integer; begin Result:=''; if (Length(S) = 0) then Exit; for iCount:=0 to Length(S)-1 do Result:=Result+S[iCount]+Delimiter; System.Delete(Result, Length(Result), 1); end; 
     var su : string; // What we want split si : TStringList; // Result of splitting Delimiter : string; ... Delimiter := ';'; si.Text := ReplaceStr(su, Delimiter, #13#10); 

    Linien in der si- Liste enthalten geteilte Strings.

    Hier ist eine Implementierung einer Explode-function, die in vielen anderen Programmiersprachen als Standardfunktion verfügbar ist:

     type TStringDynArray = array of String; function Explode(const Separator, S: string; Limit: Integer = 0): TStringDynArray; var SepLen: Integer; F, P: PChar; ALen, Index: Integer; begin SetLength(Result, 0); if (S = '') or (Limit < 0) then Exit; if Separator = '' then begin SetLength(Result, 1); Result[0] := S; Exit; end; SepLen := Length(Separator); ALen := Limit; SetLength(Result, ALen); Index := 0; P := PChar(S); while P^ <> #0 do begin F := P; P := AnsiStrPos(P, PChar(Separator)); if (P = nil) or ((Limit > 0) and (Index = Limit - 1)) then P := StrEnd(F); if Index >= ALen then begin Inc(ALen, 5); SetLength(Result, ALen); end; SetString(Result[Index], F, P - F); Inc(Index); if P^ <> #0 then Inc(P, SepLen); end; if Index < ALen then SetLength(Result, Index); end; 

    Beispielverwendung:

     var res: TStringDynArray; begin res := Explode(':', yourString); 

    Sie können Ihre eigene function erstellen, die TArray von string zurückgibt:

     function mySplit(input: string): TArray; var delimiterSet: array [0 .. 0] of char; // split works with char array, not a single char begin delimiterSet[0] := '&'; // some character result := input.Split(delimiterSet); end; 

    Ich habe diese function geschrieben, die die verknüpfte Liste getrennter Zeichenfolgen mit einem bestimmten Trennzeichen zurückgibt. Pure Free Pascal ohne Module.

     Program split_f; type PTItem = ^TItem; TItem = record str : string; next : PTItem; end; var s : string; strs : PTItem; procedure split(str : string;delim : char;var list : PTItem); var i : integer; buff : PTItem; begin new(list); buff:= list; buff^.str:=''; buff^.next:=nil; for i:=1 to length(str) do begin if (str[i] = delim) then begin new(buff^.next); buff:=buff^.next; buff^.str := ''; buff^.next := nil; end else buff^.str:= buff^.str+str[i]; end; end; procedure print(var list:PTItem); var buff : PTItem; begin buff := list; while buff<>nil do begin writeln(buff^.str); buff:= buff^.next; end; end; begin s := 'Hi;how;are;you?'; split(s, ';', strs); print(strs); end. 

    Jedi Code Library bietet eine erweiterte StringList mit integrierter Split-function, die den vorhandenen Text sowohl hinzufügen als auch ersetzen kann. Es bietet auch Referenz-gezählte Schnittstelle. Dies kann sogar mit älteren Delphi-Versionen verwendet werden, die keine SplitStrings haben und ohne sorgfältige und ein wenig mühsame Anpassungen der TStringList-Aktie, nur spezifizierte Delimiter zu verwenden.

    Zum Beispiel gegeben Textdatei von Linien wie Dog 5 4 7 kann man sie analysieren mit:

     var slF, slR: IJclStringList; ai: TList; s: string; i: integer; action: procedure(const Name: string; Const Data: array of integer); slF := TJclStringList.Create; slF.LoadFromFile('some.txt'); slR := TJclStringList.Create; for s in slF do begin slR.Split(s, ' ', true); ai := TList.Create; try for i := 1 to slR.Count - 1 do ai.Add(StrToInt(slR[i])); action(slR[0], ai.ToArray); finally ai.Free; end; end; 

    http://wiki.delphi-jedi.org/wiki/JCL_Help:IJclStringList.Split@string@string@Boolean

    Dies wird dein Problem lösen

     interface TArrayStr = Array Of string; implementation function SplitString(Text: String): TArrayStr; var intIdx: Integer; intIdxOutput: Integer; const Delimiter = ';'; begin intIdxOutput := 0; SetLength(Result, 1); Result[0] := ''; for intIdx := 1 to Length(Text) do begin if Text[intIdx] = Delimiter then begin intIdxOutput := intIdxOutput + 1; SetLength(Result, Length(Result) + 1); end else Result[intIdxOutput] := Result[intIdxOutput] + Text[intIdx]; end; end; 

    *

     //Basic functionality of a TStringList solves this: uses Classes //TStringList ,types //TStringDynArray ,SysUtils //StringReplace() ; .... //-------------------------------------------------------------------------- function _SplitString(const s:string; const delimiter:Char):TStringDynArray; var sl:TStringList; i:integer; begin sl:=TStringList.Create; //separete delimited items by sLineBreak;TStringlist will do the job: sl.Text:=StringReplace(s,delimiter,sLineBreak,[rfReplaceAll]); //return the splitted string as an array: setlength(Result,sl.count); for i:=0 to sl.Count-1 do Result[i]:=sl[i]; sl.Free; end; //To split a FileName (last item will be the pure filename itselfs): function _SplitPath(const fn:TFileName):TStringDynArray; begin result:=_SplitString(fn,'\'); end; 

    *

    Die Basis von NGLG Antwort https://stackoverflow.com/a/8811242/6619626 können Sie die folgende function verwenden:

     type OurArrayStr=array of string; function SplitString(DelimeterChars:char;Str:string):OurArrayStr; var seg: TStringList; i:integer; ret:OurArrayStr; begin seg := TStringList.Create; ExtractStrings([DelimeterChars],[], PChar(Str), seg); for i:=0 to seg.Count-1 do begin SetLength(ret,length(ret)+1); ret[length(ret)-1]:=seg.Strings[i]; end; SplitString:=ret; seg.Free; end; 

    Es funktioniert in allen Delphi-Versionen.

    Für Delphi 2010 müssen Sie eine eigene Split-function erstellen.

     function Split(const Texto, Delimitador: string): TStringArray; var i: integer; Len: integer; PosStart: integer; PosDel: integer; TempText:string; begin i := 0; SetLength(Result, 1); Len := Length(Delimitador); PosStart := 1; PosDel := Pos(Delimitador, Texto); TempText:= Texto; while PosDel > 0 do begin Result[i] := Copy(TempText, PosStart, PosDel - PosStart); PosStart := PosDel + Len; TempText:=Copy(TempText, PosStart, Length(TempText)); PosDel := Pos(Delimitador, TempText); PosStart := 1; inc(i); SetLength(Result, i + 1); end; Result[i] := Copy(TempText, PosStart, Length(TempText)); end; 

    Sie können sich darauf beziehen

     type TStringArray = array of string; var Temp2:TStringArray; Temp1="hello:world"; Temp2=Split(Temp1,':')