此行为无法更改。您无法自定义此拆分功能的工作方式。我怀疑您需要提供自己的拆分实现。 Michael Erikkson 在评论中很有帮助地指出 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.
在我的 E5530 上使用 XE7 构建的 32 位版本的输出是:
字符串。拆分:2798
StrUtils.SplitString:7167
我的分裂:1428