質問: new List(); file_list.Add("data/test01.txt"); file_list.Add("data/test02.txt"); file_list("data/test03.dat"); file_list.Add("data/test04.dat"); ``` とりあえず、FindAll等で文字列を指定して検索できることはわかったんですが、ファイル名のワイルドカード(「data/*.txt」のようなもの)にマッチする要素を取り出すにはどうしたらいいでしょうか。 ちなみに、マッチする要素1つだけではなく、マッチするすべての要素を取得したいと考えています。 何かアドバイスをいただけると幸いです。 以上、よろしくお願いいたします。
回答: コメントで紹介した3つのうち、最初の記事は色々と変なので忘れてください。 3つ目の英語版StackOverflowの記事が短くて良さそうです。 Need to perform Wildcard (*,?, etc) search on a string using Regex さらにオリジナルはこちらのようですが。 Converting Wildcards to Regexes コピーしておくと: > > > ``` > public static string WildcardToRegex(string pattern) > { > return "^" + Regex.Escape(pattern) > .Replace(@"\*", ".*") > .Replace(@"\?", ".") > + "$"; > } > > ``` > > 上記を使って`FindAll()`のパラメータにすれば、こんな風に出来ます。 ``` // 検索パターンの正規表現を作成 Regex RegexWild = new Regex(WildcardToRegex("data/*.txt"), RegexOptions.IgnoreCase); // 文字列のリストで取得 List ListResult = file_list.FindAll(s => RegexWild.IsMatch(s)); // 文字列の配列で取得 string[] ArrayResult = file_list.FindAll(s => RegexWild.IsMatch(s)).ToArray(); ``` **追記** 取り敢えずパス&ファイル指定時との互換性を高めたものを作ってみました。 突っ込みどころは色々あるでしょうが、今のところはこれまで。 ただ、それらを考えるとコメントで紹介した最初の記事は、それなりに合理的だったのかもしれません。 ``` // ワイルドカードを使用したパスから正規表現へ // From Path with Wildcard To Regex public static string PathWildcardToRegex(string pattern) { string work = "^" + Regex.Escape(pattern) .Replace(@"\*", ".*") .Replace(@"\?", ".") + "$"; work = Regex.Replace(work, @"(\\\\|/)", @"[\\/]"); // 区切り記号に'/'と'\'の両方を許す work = work.Replace(@".*\..*", @".*"); // '*.*'は'*'に変える work = work.Replace(@".*\.[\\/]", @"[^.]+[\\/]"); // Path途中の'*.'の処理 work = work.Replace(@".*\.$", @"[^.]+$"); // Path最後の'*.'の処理 return work; } ```