2016-06-26 12 views
0

私は名前が「A」で開始されているすべてのファイルは、次の3つの任意の文字と 『a123.txt』のような「.TXT」拡張子を削除する必要があります。ここでは、コードは次のようになります。のFindFirstと疑問符

var 
    sFileMask: string; 
    tsrMessage: TSearchRec; 
begin 
    sFileMask := 'c:/a???.txt'; 
    if SysUtils.FindFirst(sFileMask, 0, tsrMessage) = 0 then 
    begin 
    repeat 
     ShowMessage(tsrMessage.Name); 
    until FindNext(tsrMessage) <> 0; 
    SysUtils.FindClose(tsrMessage); 
    end; 
end; 

私は常に疑問符が、唯一の文字を意味しますが、私の驚きに、このコードが「A.TXT」、「a1.txt」を返すことを発見し、「A123と思いました。 txt "ファイル名を使用します。 "a123.txt"のようなファイルだけを探すためのコードを変更する簡単な方法はありますか?設計どおり

答えて

4

あなたの特定のニーズのための最も簡単な解決策は、これを交換することです拡張子。ダビデが言うように、そこにAPIは、フィルタリングのこの種を行う必要がありする方法はないので、あなたはそれを自分で行う必要があるでしょうが、あなたの特定のケースでは、ディレクトリ全体を列挙する必要はありません。あなたは、少なくともAPIは、それが行うことができますフィルタリングをさせ、その後、その上に独自のフィルタリングを行うことができます。

EDIT:

あなたがする必要があります(最新のコンパイラを使用して提供される
if (length(tsrMessage.Name)=8) and tsrMessage[2].IsDigit and tsrMessage[3].IsDigit and tsrMessage[4].IsDigit then ShowMessage(tsrMessage.Name); 

:あなたは「」数字です、あなたはこのようにそれを行うことができ、以下、3つの文字を確保する必要がある場合「文字」単位を含む)。また、モバイル版をコンパイルする場合は、文字列のインデックスが0で始まるので、index [1]、[2]、[3]を代わりに使用する必要があります。

古いバージョンを使用している場合は、このようにそれを行うことができます。

function IsDigit(c : char) : boolean; 
    begin 
    Result:=(c>='0') and (c<='9') 
    end; 

if (length(tsrMessage.Name)=8) and IsDigit(tsrMessage[2]) and IsDigit(tsrMessage[3]) and IsDigit(tsrMessage[4]) then ShowMessage(tsrMessage.Name); 
+0

はい私はこの方法を使いたがったが、私が使った例は単純化されていた。実際には、%03d.txtなどのように、書式のようにマスクに従ってファイルを削除する必要があります。この場合、コードは複雑すぎるので、私は何か間違っていると判断しました。 – Molochnik

+0

@Molochnik:編集セクションを参照してください... – HeartWare

4

この動作があります。ここにレイモンド・チェンによって説明されて:あなたは、コマンド・インタプリタからまったく同じ動作を確認しますHow did wildcards work in MS-DOS?

 
C:\Desktop>dir a???.txt 
Volume in drive C has no label. 
Volume Serial Number is 20DA-7FEB 

Directory of C:\Desktop 

26/06/2016 14:03     6 a.txt 
26/06/2016 14:03     6 a1.txt 
26/06/2016 14:03     6 a12.txt 
26/06/2016 14:03     6 a123.txt 
       4 File(s)    24 bytes 
       0 Dir(s) 286,381,445,120 bytes free 

あなたが望むように動作するFindFirstFile(RTLのFindFirst Windows上の背後にあるAPIを)説得する方法はありません。最適な選択肢は、ディレクトリ全体を列挙し、選択したパターンマッチングアルゴリズムを使用して独自のフィルタリングを実行することです。 +ファイル名の長さが正確に4文字+期間であることが保証されます。この

if length(tsrMessage.Name)=8 then ShowMessage(tsrMessage.Name); 

これで

ShowMessage(tsrMessage.Name); 

+0

おかげで、それを得た、私がその100%確信していたので、私は最後にこのワイルドカードを使用するので、長い時間をされています「?」正確に1文字を意味します。 – Molochnik

+0

@Molochnik SQLの1文字のワイルドカードは、記述しているとおりに動作します。多分、混乱がどこから来ているのでしょうか。私は今までそれを捉えていた。よろしく、 –

+0

@Michaelはい、それは十年のために、私は正規表現の表記法を使用してきた(以前の私はのfnmatch使用)と、それはまだ、ワイルドカードが意味することなく、常連が存在することが私の心の中に来ていない、可能性が、そうです単一の文字。 – Molochnik