| 
          
            
              | 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. 
 
 
 
 
 
 
 
 |