2016-06-29 2 views
3

私の入力は完全なパスを持つファイル名のリストになりますので、ファイル名がファイル名の形式に厳密に合致する項目のみを抽出する必要があります。ファイル形式がC#で期待どおりになっているかどうかを確認するRegex

一般的なファイル名の形式。

**c:\My\Path\To\File\fileName_YYYY-MM-DD_HH-MM-SS.ext** 

正規表現のパターンに従ってみましたが、まだノイズがあります。

string regexPattern = @"fileName_[2-9][0-9]{3}-[0-1][0-9]-[0-3][0-9]_[0-2][0-9]-[0-5][0-9]-[0-5][0-9]\.ext$" 

何か不足している場合は教えてください。あなたがのために行くことができる

+0

最初は「^」はありません。パスから実際のファイル名を切り離し、パターンチェックを_ _する。 – Nyerguds

+2

*「まだ雑音がある」* - 正確には何ですか?いくつかの例を見せていただけますか? –

+0

Ah。彼はまた、彼のドットを脱出しなかった。 – Nyerguds

答えて

0

fileName_\d{4}-\d{2}-\d{2}_\d{2}-\d{2}\.ext$ 

a demo on regex101.comを参照してください。
これがために動作します:

fileName_1234-12-12_12-12.ext 
fileName_1234-12-12_12-12.ext2 (bad extension) 
fileName_1234-12-12_12-1234.ext (longer numbers) 
/fileName_1234-12-12_12-12.ext/anythingelse (not at the right place) 
+0

日付/時刻形式のチェックで元のものよりも正確さが劣ります。 – Nyerguds

+0

@Nyerguds:真ですが、ファイル名はどこかから来ています。すべてが正規表現で行われるべきではありません(つまり、ファイル名の日付が適切であると仮定すると適切かもしれません)。 – Jan

+0

また、タイムスタンプの '秒'部分を忘れてしまい、正規表現が "filename"部分の前のテキストで始まるファイルと一致します。 – Nyerguds

0

は、これはあなたが探しているものですか?

string regexPattern = @"\\filename_[2-9]\d{3}-[0-1]\d-[0-3]\d_[0-2]\d-[0-5]\d-[0-5]\d\.ext$" 

変更はコメントに答えるために作られた、ありがとうございました。

+0

拡張子の前にドットをエスケープしないで、ファイル名の開始が実際にファイル名の先頭かどうかをチェックしません。 – Nyerguds

0

ファイル名がゴミで始まらないことを確認するソリューションはありません。ここに私のショットです:

\\\w+_[2-9]\d{3}-[0-1]\d-[0-3]\d_[0-2]\d-[0-5]\d-[0-5]\d\.ext 

ファイル名の前にバックスラッシュがあるかどうかチェックしてから、かなり基本的なマッチングです。

See it here at regex101

+0

それは難しくありません。これは正規表現だけでなく、C#の質問です。あらかじめファイル名を分割し、それだけをチェックし、正規表現が '^ $'で囲まれていることを確認してください。 – Nyerguds

+0

@Nyerguds Hmm ...正規表現の冒頭に '\\'を追加するか、それを行うためにコーディングする...私は私の提案と一緒に行くと思う;) – ClasG

+0

これは、指定されたファイル名には常にパス、しかし、。そうではないかもしれない。 – Nyerguds

0

REGEXが正しく書かれていますか?指定する書式は**c:\My\Path\To\File\fileName_YYYY-MM-DD_HH-MM-SS.ext**ですが、チェックする式は次のとおりです。@"filename[2-9][0-9]{3}-[0-1][0-9]-[0-3][0-9]_[0-2][0-9]-[0-5][0-9]-[0-5][0-9].ext$"

アンダースコアが不足しているようです。

そうでなければ一見一見正しいと思われる。あなたは、このためのパーサで構築DateTimeの使用することができたときに

3

なぜ正規表現を使用します。

string input = c:\My\Path\To\File\fileName_YYYY-MM-DD_HH-MM-SS.ext; 
string filename = Path.GetFilenameWithoutExtension(input); 

string[] parts = filename.Split('_'); 
if (parts.Length != 3) { /*Invalid*/ } 

if (Path.GetExtension(input) != "ext") { /*Invalid*/ } 

if (parts[0] != "filename") { /*Invalid*/ } 

DateTime dt; 
if (!DateTime.TryParseExact(parts[1] + "_" + parts[2], "yyyy-MM-dd_HH-mm-ss", 
    CultureInfo.InvariantCulture, DateTimeStyles.None, out dt)) 
{ /*Invalid*/ } 

//IsValid 
+0

私はこれが日付解析を扱うのを避けるので、この1つが好きです。しかし、私は共通部分のための正規表現のアプローチの分割をドロップします: 'var match = Regex.Match(Path.GetFileName(input)??"、@ "^(?。*?)(? \ d { 2} - \ d {2} - \ d {2})(?。*?)$ ");';後で 'match.Groups [" datetime "]を実行することができます。値' –

+0

Heh。非常に完全、はい。私は個人的にはSplitを使うのではなく最初の '_'のインデックスを部分的に分割するだけです。なぜなら、とにかく最後の2つの部分を連結しているからです。しかし、より多くのコードが必要になります。 – Nyerguds

+0

@Nyergudsドミトリー・バイチェンコ(Dmitry Bychenko)は、あなたが提案した部分文字列を除いて私と同じことをしました – TheLethalCoder

2

をそれはちょうどうるう年を想像し、Dateを検証するために正規表現を作成するには、かなりのことです。単に拡張子,接頭辞接尾辞を検証するのはなぜですか? サフィックスを検証する際 それはDateTime.TryParse使用することは非常に便利です:ここに流れる回答の

String path = @"c:\My\Path\To\File\fileName_2016-02-29_23-56-59.ext"; 

    // extension ".ext" 
    String ext = Path.GetExtension(fileName); 
    // file name - "fileName_2016-02-29_23-56-59" 
    String fileName = Path.GetFileNameWithoutExtension(path); 
    // filename prefix "filename" 
    String prefix = fileName.Substring(0, fileName.IndexOf('_')); 
    // filename suffix "2016-02-29_23-56-59" 
    String suffix = fileName.Substring(fileName.IndexOf('_') + 1); 

    DateTime dt; 

    bool valid = ext.Equals(".ext", StringComparison.InvariantCultureIgnoreCase) && 
       prefix.Equals("fileName") && 
       DateTime.TryParseExact(suffix, 
       "yyyy-MM-dd_HH-mm-ss", 
       CultureInfo.InvariantCulture, 
       DateTimeStyles.None, 
       out dt); 
+0

公正であるためには、このような形式のファイルは、これらの日付で作成されたファイルである可能性が高くなります。質問は、ファイル名から日付を抽出するのではなく、パターンを照合することです。 – Nyerguds

+0

@Nyerguds:*正規表現*を提案された方法(IMHOは最善の選択ではない)で*検証する*( "ファイル形式が期待どおりであるかどうかを確認する")と思う。だから私の答えでは、正規表現を使わないで検証をしました。 –

+0

真。あなたは、Windowsファイルシステムの大文字と小文字の区別を考慮しませんでした。私は 'StringComparison.InvariantCultureIgnoreCase'を提案します。 – Nyerguds

0

たくさんの...それらのどれもかかわらず、完全なようではありません。

String path = @"c:\My\Path\To\File\fileName_YYYY-MM-DD_HH-MM-SS.ext" 
String filename = new FileInfo(path).Name 
String regexPattern = @"^filename_[2-9]\d{3}-[0-1]\d-[0-3]\d_[0-2]\d-[0-5]\d-[0-5]\d\.ext$" 
Boolean isMatch = Regex.IsMatch(filename, regexPattern, RegexOptions.IgnoreCase); 

すべてをカバーする必要があります。

0

このような状況でRegexを使用したくない人は、DateTime.TryParseExact関数の動作を分けてみたいと思います。

 Func<string, string, bool> CheckFileFormat = (fileName, fileMask) => 
     { 
      DateTime parsedFileDate;     
      return DateTime.TryParseExact(fileName, fileMask, null, System.Globalization.DateTimeStyles.None, out parsedFileDate); 
     }; 


     string FileNameFormat = "'My_File_Name_'yyyy-MM-dd_HH-mm-ss'.csv'"; 
     string FileName = "My_File_Name_2017-10-11_15-46-16.csv"; 

     if (CheckFileFormat(FileName,FileNameFormat)) 
     { 
      Console.WriteLine($"file matches"); 
     } 
     else 
     { 
      Console.WriteLine("no match!"); 
     } 

     Console.ReadLine(); 
関連する問題