当最后一个值为空时,String.Split工作异常 [英] String.Split works strange when last value is empty

查看:131
本文介绍了当最后一个值为空时,String.Split工作异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将我的字符串拆分为数组,但最后一个值为空时,它的效果不好。请看我的例子。是bug还是功能?有没有办法使用这个功能没有解决办法?

I'd like to split my string to array but it works bad when last "value" is empty. See my example please. Is it bug or feature? Is there any way how to use this function without workarounds?

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)


推荐答案

p>此行为无法更改。您无法自定义此拆分功能的工作原理。我怀疑你需要提供自己的拆分实现。 Michael Erikkson在一则评论中指出: System.StrUtils.SplitString 的行为方式与您所需要的一样。

This behaviour can't be changed. There's no way for you to customise how this split function works. I suspect that you'll need to provide your own split implementation. Michael Erikkson helpfully points out in a comment that System.StrUtils.SplitString behaves in the manner that you desire.

我的设计似乎很差。例如

The design seems to me to be poor. For instance

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

然而

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

清楚指示设计不良。令人惊讶的是,测试没有确定这一点。

This asymmetry is a clear indication of poor design. It's astonishing that testing did not identify this.

设计如此明显的怀疑意味着可能值得提交错误报告。我期望它被拒绝,因为任何更改将影响现有的代码。但你永远不会知道

The fact that the design is so clearly suspect means that it may be worth submitting a bug report. I'd expect it to be denied since any change would impact existing code. But you never know.

我的建议:


  1. 使用您自己的拆分实现,按需要执行。

  2. 提交错误报告。






虽然 System.StrUtils.SplitString 做你想要的,它的表现不是很好。这很可能并不重要。在这种情况下你应该使用它。但是,如果性能很重要,那么我提供这个:


Whilst System.StrUtils.SplitString does what you want, its performance is not great. That very likely does not matter. In which case you should use it. However, if performance matters, then I offer this:

{$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位版本生成的输出是:

The output of a 32 bit release build with XE7 on my E5530 is:


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

这篇关于当最后一个值为空时,String.Split工作异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆