函数如下:
procedure GetDataFromHtml(aStr:AnsiString; Var aList: TStringList;aSplitTag:String);
var
  TmpStr  : AnsiString ;
  TmpStr1,xmlTag : String;
  StartPos,EndPos  : Integer;
  lStartPos,lEndPos  : Integer;
begin
  aList.Clear;
  TmpStr := aStr;  While Pos('>',TmpStr)>0 do
  begin
       StartPos := Pos('>',TmpStr) ;
       xmlTag := Copy(TmpStr,0,StartPos);//获取标签内容
      TmpStr := Copy(TmpStr,StartPos + 1,Length(TmpStr));//去除标签钱内容      //分段
      if Pos(aSplitTag,xmlTag) > 0 then
        alist.Add('') ;      EndPos := Pos('<',TmpStr)-1 ;
      if EndPos>0 then
      begin
        TmpStr1 := Copy(TmpStr,0,EndPos);
        if TmpStr1 <> '' then
          alist.Add(TmpStr1) ;
      end;
  end;
end;   该函数的作用是将HTML代码去除<>括号内的全部内容保存到aList当中。但是当网页内容很大(30W字符)时该函数运行较慢。
   各位大侠看谁能帮忙优化优化,拜谢!

解决方案 »

  1.   

    不要用Copy,如果可以用system.delete(,,,)过程.
    如果是Delphi7,可以用POSEX函数,
    你的代码主要消耗在Copy上了.
      

  2.   

    to xthmpro_cn(安徽农民*在外打工) 谢谢
    测试表明POSEX函数比pos慢
      

  3.   

    那你就用Pos搭配System.Delete(,,,)使用,感觉要比Copy方式块.
      

  4.   

    To xthmpro_cn(安徽农民*在外打工) 谢谢测试过了System.Delete(,,,)确实要快点,但是没有明显的改善。在算法方面可否还有优化的空间?
      

  5.   

    给个简单的HTML数据和得到的结果看看
    我试试
      

  6.   

    data:
    <field1>field1</field1>
    <field2>field</field2>
    <space></space>
    <field3>field3</field3>
    <field4>field4</field4>GetDataFromHtml(data, List, 'space')
    得到List的结果:
    field1
    field2field3
    field4是不是这样?
      

  7.   

    TO saoren(saoren) 
    是啊,没错。用来分析网页用的
      

  8.   

    测试一下:
    aStr:=AnsiReplaceText(aStr, '<',  #13);
    aStr:=AnsiReplaceText(aStr, '>',  #13);如果
    if Pos(aSplitTag,xmlTag) > 0 then
            alist.Add('') ;
    可以换成
    if aSplitTag = xmlTag then
            alist.Add('') ;则可换成
    aStr:=AnsiReplaceText(aStr, '<'+ aSplitTag +'>',  #13 + ' '+ #13);alist.text:=aStr注意AnsiReplaceText和AnsiReplaceStr我不知道那个是区分大小写的了.
      

  9.   

    感谢 xthmpro_cn(安徽农民*在外打工)兄,
      
     先测试一下。
      

  10.   

    procedure GetDataFromHtml(AList: TStringList; const ASource, ASplitTag: string);
    var
      Buffer: PChar;
      BufVal: Integer;  procedure AddLine(Buf: PChar; Size: Integer);
      begin
        if Size > 0 then
          Move(Buf^, (Buffer + BufVal)^, Size);
        Inc(BufVal, Size);
        (Buffer + BufVal)[0] := #10;
        Inc(BufVal);
      end;  function _StrPos(Sub, Source: PChar; SrcLen, SubLen: Integer): PChar;
      var
        I, J, CurrPos: Integer;
      begin
        Result := nil;
        if (SrcLen = 0) or (SubLen = 0) then Exit;    CurrPos := 0;
        while CurrPos < SrcLen do
        begin
          I := 0;
          J := CurrPos;
          while (I < SubLen) and (J < SrcLen) and ((Sub[I] = Source[J]) or (UpCase(Sub[I]) = UpCase(Source[J]))) do
          begin
            Inc(I);
            Inc(J);
          end;
          if I = SubLen then
          begin
            Result := Source + CurrPos;
            break;
          end;
          Inc(CurrPos);
        end;
      end;var
      TagLen: Integer;
      P, S, Tag, StartTag, EndTag: PChar;
    begin
      AList.Clear;
      BufVal := 0;
      Buffer := AllocMem(Length(ASource));
      try
        P := PChar(ASource);
        S := P;
        Tag := PChar(ASplitTag);
        TagLen := Length(ASplitTag);
        while True do
        begin
          if P^ = #0 then break;
          while not (P^ in ['<', #0]) do Inc(P);
          if P^ = #0 then break;
          Inc(P);
          StartTag := P;
          while not (P^ in ['>', #0]) do Inc(P);
          EndTag := _StrPos(Tag, StartTag, P - StartTag, TagLen);
          if Assigned(EndTag) then
            AddLine(nil, 0);      Inc(P);
          S := P;
          while not (P^ in ['<', #0]) do Inc(P);
          if P^ = #0 then break;
          AddLine(S, P - S);      Inc(P);
          while not (P^ in ['>', #0]) do Inc(P);
          if P^ = #0 then break;
          Inc(P);
        end;
      finally
        AList.SetText(Buffer);
        FreeMem(Buffer);
      end;
    end;const
      HTMLData =
        '<field1>field1</field1>'+
        '<field2>field</field2>'+
        '<space></space>'+
        '<field3>field3</field3>'+
        '<field4>field4</field4>';procedure TForm1.Button1Click(Sender: TObject);
    var
      List: TSTringList;
    begin
      LIst := TStringList.Create;
      try
        GetDataFromHtml(List, HTMLData, 'space');
        ShowMessage(List.Text);
      finally
        List.Free;
      end;
    end;
      

  11.   

    如果还有速度问题,估计就是TStringList的问题了,不过基本上问题不大吧,30W,也就300K,我以前解析过10M的数据也是差不多是这种方法,不过没用StringList就是了
      

  12.   

    感谢saoren(saoren)确实速度快了很多。
    再次感谢!!我会给分的。
      

  13.   

    感谢saoren(saoren)兄,本想多给点分,但是好像只能最多给100分了。