字串抓取的問題 |
尚未結案
|
saningamour
一般會員 發表:18 回覆:17 積分:7 註冊:2003-11-17 發送簡訊給我 |
請教一下各位前輩
小弟目前有一串字串
如
AAA | AAA1 | BB | BB3 | CCCCCCCCC|DDDDD^
EEEE| FFFFF| GG|GGGG|HHHHHHH|III^ 就是每個小字串中間 是以" | "來作區隔
斷行符號則是"^"
可是有沒有辦法能夠個別的置換這些 "|" 字元呢?
如每一行的第一個"|" 置換成","
第二個"|"則是換成"交互作用"
然後 第三個"|"與第四個"|"符號之間的字串(BB3 與 GGGG)則可以變色
感謝各位前輩的指教喔
|
azurecloud
中階會員 發表:52 回覆:108 積分:92 註冊:2003-09-04 發送簡訊給我 |
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 發送簡訊給我 |
下面這三個字串處理函式是從 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 發送簡訊給我 |
|
saningamour
一般會員 發表:18 回覆:17 積分:7 註冊:2003-11-17 發送簡訊給我 |
|
azurecloud
中階會員 發表:52 回覆:108 積分:92 註冊:2003-09-04 發送簡訊給我 |
|
saningamour
一般會員 發表:18 回覆:17 積分:7 註冊:2003-11-17 發送簡訊給我 |
|
azurecloud
中階會員 發表:52 回覆:108 積分:92 註冊:2003-09-04 發送簡訊給我 |
|
azurecloud
中階會員 發表:52 回覆:108 積分:92 註冊:2003-09-04 發送簡訊給我 |
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 發送簡訊給我 |
真的很感激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前輩的指導喔 ^^
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |