Данное поведение не может быть изменено. Невозможно настроить, как эта функция разделения работает. Я подозреваю, что вам нужно будет предоставить свою собственную раздельную реализацию. Майкл Эрикссон в своем замечании замечает, что System.StrUtils.SplitString
ведет себя так, как вам хочется.
Дизайн кажется мне бедным. К примеру
Length('a;'.Split([';'])) = 1
и еще
Length(';a'.Split([';'])) = 2
Эта асимметрия является четким признаком плохого дизайна. Удивительно, что тестирование не выявило этого.
Тот факт, что дизайн настолько четко подозревается, означает, что, возможно, стоит представить отчет об ошибке. Я ожидаю, что это будет отклонено, поскольку любое изменение повлияет на существующий код. Но ты никогда не знаешь.
Мои рекомендации:
- Используйте собственную реализацию разделения, который выполняет, как вам требуется.
- Отправить отчет об ошибке.
Хотя System.StrUtils.SplitString
делает то, что вы хотите, его производительность не велика. Это, скорее всего, не имеет значения. В этом случае вы должны использовать его. Однако, если производительность имеет значение, то я предлагаю следующее:
{$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.
Выход 32 разрядного выпуска сборки с XE7 на моем E5530 является:
string.Split: 2798
StrUtils.SplitString: 7167
MySplit: 1428
Именно так оно и было спроектировано. Если вам это не нравится, напишите свою собственную функцию разделения. –
Хорошо, спасибо Дэвиду. –
Что происходит с '; x'? Вы получаете одно значение или два? Если вы получаете два, тогда дизайн несимметричен, это плохо. –