お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"ワイルドカード処理(長文)"

この発言に対し以下のコメントが寄せられています
#00836 わいわい さん ワイルドカード処理(2)

別の会議室で少し前に話題になっていた*や?を 含んだファイル名のチェックです。 長いソースです。(よりよい方法がありましたら どなたかお願いします。(^^;)) このソースのみそは、maskのstringをいったん 整えることです。例えば******.*****は*.*と 同じです。同様に*?*?*?a*?*.*?は???*a?*.?*と 同じことになります。後は力技です。なお、 ooo*.又はooo*?.のように、ワイルドカード+.で 終る場合はooo*.*又はooo?*.*と同等になる ようです。 by Quiri(JAC01052) function TForm1.Check_LongMask(filename, longmask: string): boolean; var SL:TStringlist; S1,S2:string; i:integer; begin SL:=TStringList.Create; result:=false; {-----longmaskを;で区切ってSLに収納する。----} S1:=''; for i:=1 to Length(WideString(longmask)) do begin S2:=copy(WideString(longmask),i,1); if S2<>';' then begin S1:=S1+S2; end else begin if S1<>'' then SL.Append(S1); S1:=''; end; end; if S1<>'' then SL.Append(S1); {短いMask一つ一つ適合するかチェックし、 一つでも合えば結果を真にして終了} for i:=0 to SL.Count-1 do begin S1:=SL.Strings[i]; if Check_ShortMask(filename,S1) then begin result:=true; break; end; end; SL.Free; end; function TForm1.Check_ShortMask(filename, shortmask: string): boolean; var flag_n,flag_a:boolean; S1,S2,S_next:string; i,i_mask,i_file: integer; xi_mask,xi_file: integer; length_mask,length_filename: integer; num_a,num_q: integer;{*の数、?の数} begin {---------maskの形を整える。--------------} length_mask:=length(widestring(shortmask)); num_a:=0; num_q:=0; S1:=''; for i_mask:=1 to length_mask do begin S2:=copy(WideString(shortmask),i_mask,1); if S2='*' then inc(num_a) else if S2='?' then inc(num_q) else begin {*,?以外の文字がでたらそこまでの 文字列を整理する。} if num_q>0 then for i:=1 to num_q do S1:=S1+'?'; if num_a>0 then S1:=S1+'*'; S1:=S1+S2; num_a:=0; num_q:=0; end; end; {文字列の終りについている*,?の分} if num_q>0 then for i:=1 to num_q do S1:=S1+'?'; if num_a>0 then S1:=S1+'*'; {最後が.の時の処理} if copy(WideString(S1), length(WideString(S1)),1)='.' then if copy(WideString(S1), length(WideString(S1))-1,1)='*' then S1:=S1+'*'; {----------新しいMaskで比較開始-------------} length_mask:=length(widestring(S1)); length_filename:=length(widestring(filename)); result:=false; i_mask:=1; i_file:=1; xi_mask:=1; xi_file:=1; flag_a:=true; repeat S2:=copy(WideString(S1),i_mask,1); if S2='?' then begin if i_file>length_filename then exit; {?には長さがあるのでfilenameの長さが 足りなくては合致することはない。} if (i_mask=length_mask) and (i_file=length_filename) then begin {最後の文字どうしでぴたり合致した。} result:=true; exit; end; inc(i_mask); inc(i_file); end else if S2='*' then begin if i_mask=length_mask then begin {*は長さ0からいくつでも可なので、 ここまで合致していて、これ以上比較する ものがなければ全て合致するはず。} result:=true; exit; end; S_next:=copy(WideString(S1),i_mask+1,1); {*の次の文字を得る。} flag_n:=true; for i:=i_file to length_filename do if comparetext(S_next, copy(WideString(filename),i,1))=0 then begin {一致する文字が見つかった。しかし その後にも一致する文字がある可能性 があるのでとりあえず、flag_aをたて また、見つかった位置を保管。} flag_a:=false; flag_n:=false; xi_mask:=i_mask; xi_file:=i; break; end; if flag_n then exit; {*の次の文字と一致する文字が 見つからなかった。} inc(i_mask); i_file:=xi_file; end else if comparetext(S2, copy(WideString(filename),i_file,1))=0 then begin if (i_mask=length_mask) and (i_file=length_filename) then begin {最後の文字どうしでぴたり合致した。} result:=true; exit; end; inc(i_mask); inc(i_file); end else begin {不一致、しかし前にやり直すべき場所が ある可能性がある。*の位置へ戻る。} if flag_a then exit; flag_a:=true; i_mask:=xi_mask; i_file:=xi_file+1; end; until false; end; Original document by Quiri 氏 ID:(JAC01052)



ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum