Delphi Programming / Object Pascal
[掲載 2014年07月16日] [更新 2014年07月16日] Delphi サンプルプログラム集 |
778_ワイルドカードでファイル名をチェック |
動作確認等 |
Windows 7 U64(SP1) + Delphi XE(UP1) Pro |
|
778_FileName_WildCard.zip [1,754 KB] 2014年07月16日版 (EXE 同梱) |
ファイル名やディレクトリ名,パス名が,下表のような,指定したワイルドカードに一致するかをチェックするサンプルです.
TMask を使用します.TMask は少なくても Delphi 5 には実装されています.
Windows のファイル名は,Unix とは違い,大文字と小文字の区別はありません.したがって,ワイルドカードで指定する文字も大文字と小文字の区別はありません.
タイトルはファイル名となっていますが,実際には,文字列がワイルドカードに一致するかのチェックです.
|
ワイルドカード |
説明 |
* |
任意の長さの文字列 (長さ 0 も含まれる) |
? |
任意の 1 文字 |
[] |
[] 内の任意の 1 文字
- を使用して,範囲の指定も可能.例えば [A-Z] は A ~ Z のいずれかの文字 |
[!] |
! の後の任意の文字ではない 1 文字
- を使用して,上の [] と同じように範囲の指定が可能 |
Delphi 2010 以降の TDirectory の GetFiles 関数では,引数で,上の表のワイルドカードが指定できます.また,望まない結果を除去する方法も用意されています.
したがって,本ページのサンプルは,
- FindFirst と FindNext を使用してディレクトリ内のファイルを列挙する
- 既にあるファイル名のリストから,ワイルドカードに一致するファイルだけを取り出す
場合の参考コードです.ただし,ディレクトリ内のファイルのリストの取得に,Delphi 2010 以降で使用可能な TDirectory.GetFiles を使用しています.Delphi 2009 以前の場合は,以下のリンクの記事を参考してください.
FindFirst と FindFirstFile 関数を使用したディレクトリやファイルの検索でもワイルドカードを指定できますが,上の表の [] を使用したワイルドカードは指定できません.次項以降のサンプルコードのように,取得したファイル名 (文字列) に対しての操作となります.
|
ワイルドカードではなく,文字列に,文字列の集合 (文字列配列) のどれかと同じであるかをチェックするには,上の参考リンクの正規表現の記事にも参考コードがありますが,StrUtils.MatchText
等の関数も利用できます.
|
リスト1
TDirectory.GetFiles では,引数でワイルドカードを指定できる (Delphi 2010 以降) |
//=============================================================================
// フォーム表示開始時の処理
// デフォルトのワイルドカードを設定
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
Edit1.Text := '*.*';
end;
//=============================================================================
// 指定ディレクトリ内の,指定パターンに一致するファイル名をリスト
// TDirectory.GetFilesの引数で,ワイルドカードを指定する
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
ADir : String;
FilesList : TStringDynArray;
i : Integer;
FileName : String;
begin
ADir := ExtractFileDir(Application.ExeName);
if FileCtrl.SelectDirectory('検索フォルダ指定', '', ADir) then begin
Memo1.Lines.Clear;
Memo1.Lines.BeginUpdate;
//ファイルのリストを取得
//指定のパターンに一致するファイル名だけを取り出す
FilesList := TDirectory.GetFiles(ADir, Trim(Edit1.Text));
for i := 0 to Length(FilesList) - 1 do begin
FileName := TPath.GetFileName(FilesList[i]);
Memo1.Lines.Add(FileName);
end;
Memo1.Lines.EndUpdate;
end;
end;
01_TMask の Matches メソッドを使用したテスト |
TMask の Matches メソッドを使用する例です.実行時に TMask のインスタンスを生成します. |
|
図1
設計時画面
|
|
図2
テストに使用したファイルのリスト |
下図は,実際にワイルドカードを指定してテストした結果です. |
|
図3
全てのファイル
|
|
図4
拡張子の前が ject1 であるファイル |
|
図5
途中に . (ドット) があるファイル |
|
図6
先頭が A で,次が連続した 3 桁の数字のファイル |
|
図7
途中に連続した 3 桁の数字がないファイル |
|
図8
拡張子が .txt だけのファイル |
リスト2
ワイルドカードに一致するファイル名だけをリスト |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses Masks, FileCtrl, Types, IOUtils;
{$R *.dfm}
//=============================================================================
// フォーム表示開始時の処理
// デフォルトのワイルドカードを設定
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
Edit1.Text := '*.*';
end;
//=============================================================================
// 指定ディレクトリ内の,ワイルドカードに一致するファイルをリスト
// TMaskのMatchesメソッドを使用
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
ADir : String;
FilesList : TStringDynArray;
i : Integer;
FileName : String;
FileNameMask : TMask;
begin
ADir := ExtractFileDir(Application.ExeName);
if FileCtrl.SelectDirectory('検索フォルダ指定', '', ADir) then begin
Memo1.Lines.Clear;
Memo1.Lines.BeginUpdate;
FileNameMask := TMask.Create(Trim(Edit1.Text));
try
//ファイルのリストを取得
FilesList := TDirectory.GetFiles(ADir);
//ファイルのリストからワイルドカードに一致するファイル名だけを取り出す
for i := 0 to Length(FilesList) - 1 do begin
FileName := TPath.GetFileName(FilesList[i]);
if FileNameMask.Matches(FileName) then begin
Memo1.Lines.Add(FileName);
end;
end;
Memo1.Lines.EndUpdate;
finally
FileNameMask.Free;
end;
end;
end;
end.
02_Mask.pas の MatchesMask 関数を使用したテスト |
Mask.pas に実装されている MatchesMask 関数を使用する例です.
MatchesMask 関数は,内部で TMask のインスタンスを生成し,前項のサンプルで使用した Matches メソッドを実行しています.実行結果は上のサンプルと同じです. |
[備考]
Delphi 2010 以前の Delphi の MatchesMask 関数は,メモリリークが発生するようです.筆者の環境の Delphi XE 以降ではメモリリークは確認されていません.
Delphi XE (Build: 15.0.3573.25335) で修正されたようです. |
リスト3
ワイルドカードに一致するファイル名だけをリスト |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses Masks, FileCtrl, Types, IOUtils;
{$R *.dfm}
//=============================================================================
// フォーム表示開始時の処理
// デフォルトのワイルドカードを設定
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
Edit1.Text := '*.*';
end;
//=============================================================================
// 指定ディレクトリ内の,ワイルドカードに一致するファイルをリスト
// Masks.pasのMatchesMask関数を使用
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
ADir : String;
FilesList : TStringDynArray;
i : Integer;
FileName : String;
begin
ADir := ExtractFileDir(Application.ExeName);
if FileCtrl.SelectDirectory('検索フォルダ指定', '', ADir) then begin
Memo1.Lines.Clear;
Memo1.Lines.BeginUpdate;
//ファイルのリストを取得
FilesList := TDirectory.GetFiles(ADir);
//ファイルのリストからワイルドカードに一致するファイル名だけを取り出す
for i := 0 to Length(FilesList) - 1 do begin
FileName := TPath.GetFileName(FilesList[i]);
if Masks.MatchesMask(FileName, Trim(Edit1.Text)) then begin
Memo1.Lines.Add(FileName);
end;
end;
Memo1.Lines.EndUpdate;
end;
end;
end.
|