gpt4 book ai didi

delphi - 当最后一个值为空时 String.Split 工作很奇怪

转载 作者:行者123 更新时间:2023-12-03 15:36:21 24 4
gpt4 key购买 nike

我想将字符串拆分为数组,但当最后一个“值”为空时效果不佳。请看我的例子。这是错误还是功能?有什么方法可以在没有解决方法的情况下使用此功能吗?

var
arr: TArray<string>;

arr:='a;b;c'.Split([';']); //length of array = 3, it's OK
arr:='a;b;c;'.Split([';']); //length of array = 3, but I expect 4
arr:='a;b;;c'.Split([';']); //length of array = 4 since empty value is inside
arr:=('a;b;c;'+' ').Split([';']); //length of array = 4 (primitive workaround with space)

最佳答案

此行为无法更改。您无法自定义此拆分功能的工作方式。我怀疑您需要提供自己的拆分实现。迈克尔·埃里克森 (Michael Erikkson) 在评论中指出 System.StrUtils.SplitString以您希望的方式行事。

在我看来,这个设计很糟糕。例如

Length('a;'.Split([';'])) = 1

但是

Length(';a'.Split([';'])) = 2

这种不对称明显表明设计不佳。令人惊讶的是,测试并未发现这一点。

事实上,该设计明显可疑,这意味着可能值得提交错误报告。我预计它会被拒绝,因为任何更改都会影响现有代码。但你永远不知道。

我的建议:

  1. 使用您自己的拆分实现,根据您的需要执行操作。
  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 位发布版本的输出是:

string.Split: 2798StrUtils.SplitString: 7167MySplit: 1428

关于delphi - 当最后一个值为空时 String.Split 工作很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30759737/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com