Tego zachowania nie można zmienić. Nie ma sposobu, aby dostosować sposób działania tej funkcji podziału. Podejrzewam, że musisz podać własną implementację podziału. Michael Erikkson pomocnie wskazuje w komentarzu, że System.StrUtils.SplitString
zachowuje się w sposób, w jaki pragniesz.
Wygląda na to, że projekt jest kiepski. Na przykład
Length('a;'.Split([';'])) = 1
i jeszcze
Length(';a'.Split([';'])) = 2
Ta asymetria jest wyraźne wskazanie złej konstrukcji. To zadziwiające, że testy tego nie zidentyfikowały.
Fakt, że projekt jest tak wyraźnie podejrzany, oznacza, że warto złożyć zgłoszenie błędu. Oczekuję, że odmówi, ponieważ każda zmiana wpłynie na istniejący kod. Ale nigdy nie wiesz.
Moje zalecenia:
- Użyj własnego wdrożenie podziału, który wykonuje, jak potrzebujesz.
- Zgłoś zgłoszenie błędu.
Podczas System.StrUtils.SplitString
robi to, co chcesz, jego wydajność nie jest wielki. To bardzo prawdopodobne, nie ma znaczenia. W takim przypadku powinieneś go użyć. Jednakże, jeśli kwestiach wydajności, a potem zaoferować to:
{$APPTYPE CONSOLE}
uses
System.SysUtils, System.Diagnostics, System.StrUtils;
function MySplit(const s: string; Separator: char): TArray<string>;
var
i, ItemIndex: Integer;
len: Integer;
SeparatorCount: Integer;
Start: Integer;
begin
len := Length(s);
if len=0 then begin
Result := nil;
exit;
end;
SeparatorCount := 0;
for i := 1 to len do begin
if s[i]=Separator then begin
inc(SeparatorCount);
end;
end;
SetLength(Result, SeparatorCount+1);
ItemIndex := 0;
Start := 1;
for i := 1 to len do begin
if s[i]=Separator then begin
Result[ItemIndex] := Copy(s, Start, i-Start);
inc(ItemIndex);
Start := i+1;
end;
end;
Result[ItemIndex] := Copy(s, Start, len-Start+1);
end;
const
InputString = 'asdkjhasd,we1324,wqweqw,qweqlkjh,asdqwe,qweqwe,asdasdqw';
var
i: Integer;
Stopwatch: TStopwatch;
const
Count = 3000000;
begin
Stopwatch := TStopwatch.StartNew;
for i := 1 to Count do begin
InputString.Split([',']);
end;
Writeln('string.Split: ', Stopwatch.ElapsedMilliseconds);
Stopwatch := TStopwatch.StartNew;
for i := 1 to Count do begin
System.StrUtils.SplitString(InputString, ',');
end;
Writeln('StrUtils.SplitString: ', Stopwatch.ElapsedMilliseconds);
Stopwatch := TStopwatch.StartNew;
for i := 1 to Count do begin
MySplit(InputString, ',');
end;
Writeln('MySplit: ', Stopwatch.ElapsedMilliseconds);
end.
Wyjście uwolnienie 32 bit budować z XE7 na moim E5530 jest:
string.Split: 2798
StrUtils.SplitString: 7167
MySplit: 1428
Tak właśnie zaprojektowano. Jeśli ci się nie podoba, napisz własną funkcję podziału. –
OK, dziękuję David. –
Co dzieje się z "; x"? Czy otrzymujesz jedną wartość lub dwie? Jeśli dostaniesz dwa, to projekt jest asymetryczny, coś złego. –