Diese Funktion wurde entwickelt, um aufeinanderfolgende Separatoren nicht zusammenzuführen. Betrachten wir zum Beispiel die folgende Zeichenfolge auf Kommata Aufspalten:
foo,,bar
Was würden Sie SplitString('foo,,bar', ',')
zurückkehren erwarten? Wären Sie auf der Suche nach ('foo', 'bar')
oder sollte die Antwort ('foo', '', 'bar')
sein? Es ist nicht a priori klar, was richtig ist, und verschiedene Anwendungsfälle könnten unterschiedliche Ausgaben erfordern.
In Ihrem Fall haben Sie zwei Trennzeichen angegeben: ';'
und ' '
. Das bedeutet, dass
'a'; 'b'
Splits bei ';'
und wieder bei ' '
. Zwischen diesen beiden Begrenzern gibt es nichts, und daher wird eine leere Zeichenfolge zwischen 'a'
und 'b'
zurückgegeben.
Die Methode Split
aus der string helper, die in XE3 eingeführt wurde, hat einen TStringSplitOptions
Parameter. Wenn Sie ExcludeEmpty
für diesen Parameter übergeben, werden aufeinanderfolgende Trennzeichen als einzelnes Trennzeichen behandelt. Dieses Programm:
{$APPTYPE CONSOLE}
uses
System.SysUtils;
var
S: string;
begin
for S in '''a''; ''b''; ''c'''.Split([';', ' '], ExcludeEmpty) do begin
Writeln(S);
end;
end.
Ausgänge:
'a'
'b'
'c'
Aber Sie haben nicht das für Sie in XE2 zur Verfügung, so ich glaube, Sie werden Ihre eigene Split-Funktion haben, rollen. Was wie folgt aussehen könnte:
function IsSeparator(const C: Char; const Separators: string): Boolean;
var
sep: Char;
begin
for sep in Separators do begin
if sep=C then begin
Result := True;
exit;
end;
end;
Result := False;
end;
function Split(const Str, Separators: string): TArray<string>;
var
CharIndex, ItemIndex: Integer;
len: Integer;
SeparatorCount: Integer;
Start: Integer;
begin
len := Length(Str);
if len=0 then begin
Result := nil;
exit;
end;
SeparatorCount := 0;
for CharIndex := 1 to len do begin
if IsSeparator(Str[CharIndex], Separators) then begin
inc(SeparatorCount);
end;
end;
SetLength(Result, SeparatorCount+1); // potentially an over-allocation
ItemIndex := 0;
Start := 1;
CharIndex := 1;
for CharIndex := 1 to len do begin
if IsSeparator(Str[CharIndex], Separators) then begin
if CharIndex>Start then begin
Result[ItemIndex] := Copy(Str, Start, CharIndex-Start);
inc(ItemIndex);
end;
Start := CharIndex+1;
end;
end;
if len>Start then begin
Result[ItemIndex] := Copy(Str, Start, len-Start+1);
inc(ItemIndex);
end;
SetLength(Result, ItemIndex);
end;
Natürlich setzt das alles voraus, dass ein Leerzeichen als Trennzeichen dienen soll. Sie haben im Code danach gefragt, aber vielleicht möchten Sie nur ;
als Trennzeichen fungieren. In diesem Fall möchten Sie wahrscheinlich ';'
als Trennzeichen übergeben und die zurückgegebenen Zeichenfolgen trimmen.
Lesen Sie die Dokumentation. Vielleicht nicht wie erwartet, aber es funktioniert wie dokumentiert. –
Diese Frage enthält einige Vorschläge zum Aufteilen einer Zeichenfolge basierend auf einer Zeichenfolge mit mehreren Zeichen (was Sie erwartet haben), aber die meisten davon funktionieren mit Zeichenfolgenlisten, nicht mit Arrays: http://stackoverflow.com/questions/15424293/How-to-Split-String-by-a-Multi-Zeichen-Delimiter – quasoft