快速分解字符串到列表 将字符串列表转换成用分隔符分隔的字符串 的函数,超快。

rel=File-List href="./在DB单元有一个ExtractField%20函数,也是分解用分号分隔的字符串的.files/filelist.xml"> 在DB单元有一个ExtractField 函数,也是分解用分号分隔的字符串的

DB单元有一个ExtractField 函数,也是分解用分号分隔的字符串的。所以用了 ExtractFieldName这个名称。

 

源字符串列表如下:

A@

B@;

@

;

;@@AC

 

将它转换成分分号分隔的字符串, 转换的原则为:

1.如果字符串本身中有分号则用 @ 代替,@是自己定的转义字符。

       2.如果字符串本身就有@字符,则用@@来代替

上面的源字符串的转换结果如下如下:

A@@;B@@@;;@@;@;;@;@@@@AC

 

现在要将这个字符串还原为源字符串:还原的原则为:

1.  如果遇到 @@ 则还原为  @

2.  如果遇到 @;  则还原为  ;

3.  如果遇到了单个的 @ 则保存为 @

 

因为 ;是分隔字符串,所以程序先开始查找 ;然后从找到的位置返向检查看它前面是不是有 @ 如果有还要检查有几个 如果结果Count是偶数个子说明这个 ;就分隔字符符,前面有Count/2 @ 。如果Count是奇数个@ 则说明 ;中做为字符串中的 ;号出现的,前面有 (Cout-1)/2 @

 

找到一个分隔符后将新得到字符串保存到列表中。然后将这个字符串中的 @@ 替换成 @

 

程序主要提高速度是靠 StrPos SetString

StrPos Pos 的速度快,返回的是找到的字符 Pchar 类型,是一个指针

SetString 从一个字符串中直接内存拷贝得到其中的一部分,比Copy 要快,因为Copy要使用重新分配一块内在做为返回值

 

以下代码还有可能提升的地方就是:

现在定义了变量S做为原字符串保存到列表字符串的中间变量。

如果直接能拷贝原字符串内存到列表字符串内存的话速度会更快。不知道如何实现

 

procedure ExtractFieldName(const Fields: string; var AStrList:TStringList);

Const

  CO_ESCSTR='@'; //转义符

  CO_SPACESTR=';'; //分隔符

var

  AIndexBeg,AIndexEnd:PChar; //当前检查的开始/结束字符

  APEnd:LongWord; //字符串的结束指针

 

  AEscCount:Integer;  //连接的转义字符的个数

  AEscBeg:PChar; //连接的转义字符的开始位置

 

  S:String;

  APS:PChar;

  APBegS,APEndS:LongWord; //检查分解后的字符串

begin

{分解用;分隔的字符串,将@;解释为字符串中的;}

  if Fields='' then

    Exit;

  AIndexBeg:=PChar(Fields);

  AIndexEnd:=PChar(Fields);

  APEnd:=LongWord(AIndexEnd)+Length(Fields);

 

  While LongWord(AIndexEnd)<=APEnd do

  begin

    AIndexEnd:=StrPos(PChar(AIndexEnd),CO_SPACESTR); //查找字符串中的分隔符

    if (Nil=AIndexEnd)or(LongWord(AIndexEnd)=APEnd) then

      SetString(S,AIndexBeg,PChar(APEnd)-AIndexBeg)

    else  //找到了一个分隔符号 ,检查它连续的 转义 字符的个数

    begin

      AEscCount:=0;

      AEscBeg:=AIndexEnd-1;

      While (AEscBeg[0]=CO_ESCSTR) do

      begin

        Inc(AEscCount);

        Inc(AEscBeg,-1);

      end;

      if Odd(AEscCount) then//奇数个,分隔符本身属于字符串的

      begin

        Inc(AIndexEnd);

        Continue;

      end

      else //偶数个 是分隔符

      begin

        SetString(S,AIndexBeg,AIndexEnd-AIndexBeg); //保存到列表中

        Inc(AIndexEnd);

        AIndexBeg:=AIndexEnd;

      end;

   end;

 

// @@ @; 出现 替换成 @ ;

//如果只出现 @ 则做为字符串中的存在

 

    APBegS:=LongWord(PChar(S))-1;

    APS:=PChar(S);

    APEndS:=LongWord(APS)+Length(S);

    While LongWord(APS)<APEndS do

    begin

      APS:=StrPos(PChar(APS),CO_ESCSTR); //查找 @

      if APS=Nil then

        Break

      else

      begin

        if (APS+1)[0] in [CO_SPACESTR,CO_ESCSTR] then

        begin

          Delete(S,LongWord(APS)-APBegS,1);

          APEndS:=LongWord(PChar(S))+Length(S);

        end;

        Inc(APS,1);

      end;

    end;

    AStrList.Add(S);

    if (Nil=AIndexEnd) then

      Break;

  end;

end;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值