// 分解用 ',' 分开的多个部分的字段名
  // 形如 : Field1, [Field2],[Fiel d3],[Fie, ld]
  // 结果 : FIeld1  [Field2] [Fiel d3] [Fie, ld]  四个部分
  // 参数 : List = 存放需要分解的串,及结果串(每行一个部分)
  // 返回 : True/False 表示 成功/失败
  function MakeFieldList(List : TStringList) : Boolean;
function MakeFieldList(List : TStringList) : Boolean;
var
  c : Char;
  FieldList : string;
  nPos, nLoop, nLen, nStart : Integer;
begin
  FieldList := List.Text;
  List.Clear();
  nLen := Length(FieldList);
  nLoop := 1;
  nStart := nLoop;
  while (nLoop < nLen) do begin
    c := FieldList[nLoop];
    // 进入 [..] 部分
    if (c = '[') then begin
      // 直接找结束部分
      nPos := PosEx(']', FieldList, nLoop + 1);
      // 没有找到对应的 [..] 结束
      if (nPos = 0) then begin
        List.Add(Copy(FieldList, nLoop, nLen - nLoop));
        exit;
      end;
      nLoop := nPos;
    // 处理用 ',' 分开的每个部分
    end else if (c = ',') then begin
      List.Add(Copy(FieldList, nStart, nLoop - nStart));
      nStart := nLoop + 1;
    end;
    inc(nLoop, 1);
  end;
  // 如果退出循环,还有未处理的部分
  if (nStart < nLoop) then
    List.Add(Copy(FieldList, nStart, nLoop - nStart));
  Result := True;
end;刚刚写的一个分解字段名的函数,让各位见笑了,如果有更好的算法,希望共同交流 : QQ 2195013

解决方案 »

  1.   

    function SplitString(const SourceChar, SplitChar: string): TStringList;
    var
      Tmp: string;
      I: Integer;
    begin
      Result := TStringList.Create;
      Tmp := SourceChar;
      I := Pos(SplitChar, SourceChar);
      while I <> 0 do
      begin
        Result.Add(Copy(Tmp, 0, I - 1));
        Delete(Tmp,1,i);
        I := Pos(SplitChar, Tmp);
      end;
      Result.Add(Tmp);
    end;
      

  2.   


    更正:以上算法最后部分有误,应更正为:  // 如果退出循环,还有未处理的部分
      if (nStart < nLoop) then
        List.Add(Copy(FieldList, nStart, nLoop - nStart - 1));
                                                       ^^^^
      

  3.   

    Uses XMLUtilfunction Split0(Str: string; const SubStr: string): TStringList;
    ------------------------------------
    我是一个菜鸟,菜菜菜菜菜菜菜菜
      

  4.   

    function MakeFieldList(var List:TStringList):Boolean;
    var strSource:string;
        strStack:String;
        i:Integer;
    begin
      strSource:=List.Text;
      List.Clear;
      for i:=1 to Length(strSource) do
      begin
        case strSource[i] of
          ',':
            if Trim(strStack)<>'' then
            begin
              if (Trim(strStack)[1]<>'[') then
              begin
                List.Add(Trim(strStack));
                strStack:='';
              end
              else
                strStack:=strStack+strSource[i];
            end;
          ']':
            if (Trim(strStack)<>'') and (Trim(strStack)[1]<>'[') then
            begin
              Result:=False;
              Exit;
            end
            else
            begin
              List.Add(Trim(strStack+']'));
              strStack:='';
            end;
          else
            strStack:=strStack+strSource[i];
        end;
      end;
      Result:=True;
    end;
      

  5.   

    TStringList.Delimiter 干嘛不直接用
      

  6.   

    前不久在哪个帖子看到TStringList.Delimiter 有个BUG的。------------------------------------
    我是一个菜鸟,菜菜菜菜菜菜菜菜
      

  7.   


    感谢楼上几位的参与,也试了几位提供的算法,发现: jackie168(三箭齐发)            x := SplitString(...)
     belllab(菜鸟)                  x := split0(...)的算法都能正确分解到各个部分, 但是在 function 中 TStringList.Create(), 然后返回之,请教:如果在 x Function 外部的调用程序没有 x.Free; 是否会造成内存泄漏呢??  lili1(离奇)提供的算法,我随便打一些很乱的字符(当然包含 ',' 及'[', ']' 号了),发现有BUG,不能正确分解出来。而且当 输入是 s1,s2,s3,s4 时,只能分解到 s1, s2, s3 三个部分,丢了 s4。
      

  8.   

    DB 单元的 ExtractFieldName函数就可以用 它分解的是用 ;分隔的字段名。var
     APos,L:integer;
     AFieldStr:String;
    begin
     AFieldStr:='a;b;c;d';
     APos:=1;
     L:=Length(AFieldStr);
     While APos<=L do
      ShowMessage(ExtractFieldName(AFieldStr,APos));
    end;
      

  9.   

    使用Split0这个Function,你必须显式的调用X的Free,否则肯定会造成内存泄漏,我试过了的。------------------------------------
    我是一个菜鸟,菜菜菜菜菜菜菜菜