線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1736
推到 Plurk!
推到 Facebook!

字串抓取的問題

尚未結案
saningamour
一般會員


發表:18
回覆:17
積分:7
註冊:2003-11-17

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-12-08 23:04:06 IP:218.167.xxx.xxx 未訂閱
請教一下各位前輩 小弟目前有一串字串 如 AAA | AAA1 | BB | BB3 | CCCCCCCCC|DDDDD^ EEEE| FFFFF| GG|GGGG|HHHHHHH|III^ 就是每個小字串中間 是以" | "來作區隔 斷行符號則是"^" 可是有沒有辦法能夠個別的置換這些 "|" 字元呢? 如每一行的第一個"|" 置換成"," 第二個"|"則是換成"交互作用" 然後 第三個"|"與第四個"|"符號之間的字串(BB3 與 GGGG)則可以變色 感謝各位前輩的指教喔
azurecloud
中階會員


發表:52
回覆:108
積分:92
註冊:2003-09-04

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-12-09 00:44:08 IP:163.13.xxx.xxx 未訂閱
Hi, saningamour 您好:     請看下面這個範例 ********************************************************************* procedure TForm1.Button1Click(Sender: TObject); var s,tempstr,tempstr1 : string;     i : integer;     tmpstringlist : TStringList; begin    // 將所有換行字元取代為 空白    s := 'AAA | AAA1 | BB | BB3 | CCCCCCCCC|DDDDD^';    s := s + 'EEEE| FFFFF| GG|GGGG|HHHHHHH|III^';    s := StringReplace(s,'^','',[rfReplaceAll]);       // 以 | 符號來將字串 s 拆成一個一個放在 StringList 中    tmpstringlist := TStringList.create;    SplitColumnsNoTrim(s, tmpstringlist, '|');    tempstr :='';    for i := 0 to tmpstringlist.Count - 1 do      begin         memo1.Lines.Add(tmpstringlist[i]);         if (i=1) then tempstr := tmpstringlist[i] + ',';         if (i=2) then tempstr := tempstr + tmpstringlist[i]+ '交互作用';         if (i=3) then             begin                richedit1.Clear;                tempstr := tempstr + tmpstringlist[i];                richedit1.Lines.Add(tempstr);             end;         if (i=4) then             begin                richedit1.Clear;                tempstr := tempstr + tmpstringlist[i];                richedit1.Lines.Add(tempstr);             end;      end;     with richedit1 do        begin           SelAttributes.Color := clBlack;           SelStart := 20; // 從這一行的第 n( 中文 1 字 2 byte ) 個字開始           SelLength := 3; // 同上,自己算,或是去找計算字元長度的函式           SelAttributes.Color := clblue;           SelStart := 25;           SelLength := 9;           SelAttributes.Color := clred;        end;    end; ************************************************************************    ========================
我要努力向上~~[/h5] ========================
azurecloud
中階會員


發表:52
回覆:108
積分:92
註冊:2003-09-04

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-12-09 00:47:49 IP:163.13.xxx.xxx 未訂閱
下面這三個字串處理函式是從 Indy 元件中「借」出來的,請直接貼在同一 Unit 中 ************************************************************************ // Universal "AnsiPosIdx" function. AnsiPosIdx&AnsiMemoryPos are just simple interfaces for it function  AnsiPosIdx_ (const ASubStr: AnsiString; AStr: PChar; L1: Cardinal; AStartPos: Cardinal=0): Cardinal; var   L2: Cardinal;   ByteType : TMbcsByteType;   Str, SubStr, CurResult: PChar; Begin   Result:= 0; //not found   //*L1 := Length(AStr);   L2 := Length(ASubStr);   if (L2=0) or (L2>L1) then Exit;   Str:=Pointer(AStr);   SubStr:=Pointer(ASubStr);   //posIDX   if AStartPos>0 then begin     Str := Str + AStartPos - 1;     L1  := L1 + 1 - AStartPos;   end;//if   if L1<=0 then EXIT;      CurResult := StrPos(Str, SubStr);   while (CurResult <> nil) and ((L1 - Cardinal(CurResult - Str)) >= L2) do begin //found and LenStr-Pos>=LenSubStr     ByteType := StrByteType(Str, Integer(CurResult-Str)); {$IFDEF MSWINDOWS}     if (ByteType <> mbTrailByte) and       (Windows.CompareString(LOCALE_USER_DEFAULT, 0, CurResult, L2, SubStr, L2) = 2) then begin       Result:=CurResult-Pointer(AStr)+1;       Exit;     end;//if     if (ByteType = mbLeadByte) then Inc(Result); {$ENDIF} {$IFDEF LINUX}     if (ByteType <> mbTrailByte) and       (strncmp(CurResult, SubStr, L2) = 0) then begin       Result:=CurResult-Pointer(AStr)+1;       Exit;     end;//if {$ENDIF}     Inc(Result);     CurResult := StrPos(CurResult, SubStr);   end; End;//AnsiPosIdx    function  AnsiPosIdx(const ASubStr,AStr: AnsiString; AStartPos: Cardinal=0): Cardinal; Begin   Result:=AnsiPosIdx_(ASubStr, Pointer(AStr), Length(AStr), AStartPos); End;//    procedure SplitColumnsNoTrim(const AData: String; AStrings: TStrings; const ADelim: String=' ');    {Do not Localize} var   i: Integer;   LDelim: Integer; //delim len   LLeft: String;   LLastPos: Integer; Begin   Assert(Assigned(AStrings));   AStrings.Clear;   LDelim := Length(ADelim);   LLastPos := 1;      i := Pos(ADelim, AData);   while I > 0 do begin     LLeft:= Copy(AData, LLastPos, I-LLastPos); //'abc d' len:=i(=4)-1    {Do not Localize}     if LLeft > '' then begin    {Do not Localize}       AStrings.AddObject(LLeft,Pointer(LLastPos));     end;     LLastPos := I + LDelim; //first char after Delim     i := AnsiPosIdx(ADelim, AData, LLastPos);   end;//while found   if LLastPos <= Length(AData) then begin     AStrings.AddObject(Copy(AData,LLastPos,MaxInt), Pointer(LLastPos));   end; End;//TIdFTPListItems.ParseColumns    ========================
我要努力向上~~[/h5] ========================
azurecloud
中階會員


發表:52
回覆:108
積分:92
註冊:2003-09-04

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-12-09 00:50:49 IP:163.13.xxx.xxx 未訂閱
要變色功能要用 richedit 物件,以下是我做的範例的執行圖,第二個框是richecit ************************************************************************ ========================
我要努力向上~~[/h5] ========================
saningamour
一般會員


發表:18
回覆:17
積分:7
註冊:2003-11-17

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-12-09 01:17:08 IP:218.167.xxx.xxx 未訂閱
azurecloud前輩您好 感謝你的指教喔 我用Delphi6 的確可以達到應該出現的效果 但是目前我所需要用的還是Delphi5 我用Delphi5跑的話 反而會造成CPU使用率飆到100的情況 然後整個程式就卡在那邊 請問怎會這樣呢?? ^^?? === 我忘記一件事了 Delphi5沒有Indy元件 是否因此delphi5會跑不動? 真是糟糕 >"< 發表人 - saningamour 於 2003/12/09 01:23:12
azurecloud
中階會員


發表:52
回覆:108
積分:92
註冊:2003-09-04

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-12-09 01:40:09 IP:163.13.xxx.xxx 未訂閱
Hi, saningamour 您好:    那三個函數貼在自己的 Unit 後,不需要 Indy 元件也可以執行。 至於 CPU … ;您跑的資料十分大量嗎?我的電腦測試時沒什麼問題。    若是資料大量的話可能要考慮把程序放入 Thread 中執行,字串比 對花的 CPU 時間蠻多的沒錯。    ========================
我要努力向上~~[/h5] ========================
saningamour
一般會員


發表:18
回覆:17
積分:7
註冊:2003-11-17

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-12-09 06:37:44 IP:218.167.xxx.xxx 未訂閱
azurecloud前輩您好 我測的資料量還是很小ㄝ 就 AAA | AAA1 | BB | BB3 | CCCCCCCCC|DDDDD^ EEEE| FFFFF| GG|GGGG|HHHHHHH|III^ 這樣而已 同樣的程式碼 同樣的資料量 用D6編譯出來的執行檔 跑的真的是很順 D5的話 則是會跑不出來 然後CPU時間就狂跑 整個程式就卡在哪就不會動了 真的很奇怪 ^^?
azurecloud
中階會員


發表:52
回覆:108
積分:92
註冊:2003-09-04

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-12-09 08:36:52 IP:163.13.xxx.xxx 未訂閱
Hi, saningamour 您好:          抱歉,我想了很久,也不知道為什麼,畢竟 Indy 的程式碼我也不是 很懂,要學的東西還太多了…     站上還有許多高手,也許您再等等看,不然可另外發表主題,看看有 沒有其他的前輩知道原因。    ========================
我要努力向上~~[/h5] ========================
azurecloud
中階會員


發表:52
回覆:108
積分:92
註冊:2003-09-04

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-12-09 11:09:51 IP:163.13.xxx.xxx 未訂閱
Hi, saningamour 您好:    要先向您道歉,借用 Indy 的程式碼是因為我懶得自己去寫字串函式 請你改用這個試試,用的都是 Delphi 內建的函式,已執行過,圖就不貼了。    procedure TForm1.Button1Click(Sender: TObject); var s,tempstr,tempstr1,newstr : string;     new,i,index3,index4 : integer; begin     richedit1.Clear;     richedit1.SelAttributes.Color := clBlack;     // 將所有換行字元取代為 空白     s := 'AAA | AAA1 | BB | BB3 | CCCCCCCCC|DDDDD^';     s := s + 'EEEE| FFFFF| GG|GGGG|HHHHHHH|III^';     s := StringReplace(s,'^','',[rfReplaceAll]);        tempstr :='';     newstr := '';     i := 0;     repeat        new := pos('|',s);        tempstr := trim(copy(s,0,new-1));        //showmessage(tempstr);        tempstr1 := copy(s,new+1,length(s));        s := trim(tempstr1);        //showmessage(s);        Case i of          0:             begin                tempstr := tempstr + ',';                i := i + 1;             end;          1:             begin                tempstr := tempstr + ' 交互作用 ';                i := i + 1;             end;          2..99999:             begin                tempstr := tempstr + ' ';                i := i + 1;             end;        end;        newstr := newstr + tempstr;     until (pos('|',s)=0);        // 取得第三個字串的起始位址     new := pos('用 ',newstr);     tempstr := trim(copy(newstr,0,new+2));     index3 := length(tempstr)+1;        // 取得第四個字串的起始位址     tempstr1 := copy(newstr,new+2,length(newstr));     new := pos(' ',trim(tempstr1));     tempstr := trim(copy(tempstr1,0,new+1));     index4 := index3 + length(tempstr)+1;           with richedit1 do      begin        Lines.Add(newstr);        SelStart := index3;        SelLength := index4-index3+1;        SelAttributes.Color := clblue;        SelStart := index4;        SelLength := length(newstr);        SelAttributes.Color := clred;       end;  end;    ========================
我要努力向上~~[/h5] ========================
saningamour
一般會員


發表:18
回覆:17
積分:7
註冊:2003-11-17

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-12-09 17:08:50 IP:202.39.xxx.xxx 未訂閱
真的很感激azurecloud前輩的指教喔 按照前輩的做法 真的能夠達到所要的效果 另外 我是有做點小改變 1. 把 s := 'AAA | AAA1 | BB | BB3 | CCCCCCCCC|DDDDD^'; s := s 'EEEE| FFFFF| GG|GGGG|HHHHHHH|III^'; 改成 s:='AAA | AAA1 | BB | BB3 | CCCCCCCCC|DDDDD^EEEE| FFFFF| GG|GGGG|HHHHHHH|III^'; (不拆開的原因就是因為可能會有很多筆) 2 s := StringReplace(s,'^','',[rfReplaceAll]); 改成 s := StringReplace(s,'^',''|#13#10'',[rfReplaceAll]); 因為我發現最後少一個"|" 最後的字串會漏掉(III 會不見) 3 在最後的 i:=i 1; 改成 i:=0; 這樣每段文字都能使用到 最後 還是感謝azurecloud前輩的指導喔 ^^
系統時間:2024-05-19 19:22:16
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!