使用SplitString消除空字符串

时间:2012-04-02 18:37:17

标签: string delphi parsing delphi-xe pascal

有没有办法从SplitString函数(Delphi XE,StrUtils)的动态数组中排除空字符串,而不必迭代数组?

如果没有,有人能建议最有效的方法吗?现在我这样做:

function SplitStringNoEmpty(myString : string; myDelimiters : string):TStringDynArray;
var
    words_array_pre : TStringDynArray;
    words_array_pos : TStringDynArray;
    array_length : Integer;
    actual_length : Integer;
    current_word : string;

    procedure AddElement(const Str: string);
    begin
      words_array_pos[actual_length]:= Str;
      inc(actual_length);
    end;
begin
    words_array_pre:= SplitString(myString, whitespaceNewLineCharacterSet + punctuationCharacterSet);
    array_length:= Length(words_array_pre);
    if (array_length >0) then
    begin
      actual_length:= 0;
      SetLength(words_array_pos, array_length);
      for current_word in words_array_pre do
      begin
        if (current_word <> '') then
          AddElement(current_word);
      end;
      SetLength(words_array_pos, actual_length);
      result:= words_array_pos;
    end
    else
      result:= words_array_pre;
end;

2 个答案:

答案 0 :(得分:3)

您可以编写自己的SplitString函数实现,而忽略空字符串。

检查此样本

function SplitString2(const S, Delimiters: string): TStringDynArray;
var
  LIndex, SIndex, FIndex, LMax, LPos: Integer;
  foo : string;
begin
  Result := nil;

  if S <> '' then
  begin
    LPos   := 0;
    LMax   := 0;
    SIndex := 1;

    for LIndex := 1 to Length(S) do
      if IsDelimiter(Delimiters, S, LIndex) then Inc(LMax);

    SetLength(Result, LMax + 1);

    repeat
      FIndex := FindDelimiter(Delimiters, S, SIndex);
      if FIndex <> 0 then
      begin
        foo:= Copy(S, SIndex, FIndex - SIndex);
        if foo<>'' then
        begin
          Result[LPos] := foo;
          Inc(LPos);
        end;
        SIndex := FIndex + 1;
      end;
    until (LPos = LMax) or (FIndex=0);

    if LPos<LMax then
     SetLength(Result, LPos + 1);

    foo:=Copy(S, SIndex, Length(S) - SIndex + 1);
    if foo<>'' then
     Result[LMax] := foo
    else
     SetLength(Result, LPos);
  end;
end;

答案 1 :(得分:2)

如果不迭代数组就不可能删除数组的某些元素 - 你怎么知道要删除哪些元素?对代码进行的改进是消除了分配额外数组的需要。您可以就地剔除原始数组:

function SplitStringNoEmpty(const s, delimiters: string): TStringDynArray;
var
  Src, Dest: Integer;
begin
  Result := SplitString(s, delimiters);
  if Length(Result) <> 0 then begin
    // Push all non-empty values to front of array
    Dest := 0;
    for Src := 0 to High(Result) do
      if Result[Src] <> '' then begin
        if Src <> Dest then
          Result[Dest] := Result[Src];
        Inc(Dest);
      end;
    // Remove excess from end of array
    SetLength(Result, Dest);
  end;
end;