次の関数 (これは完全に機能します) では、一致が見つかった場所だけでなく、一致が何であったか... コードを返すという課題が提示されました。
txtFilePattern は、パイプで区切られたファイル拡張子のリストです。txtKeywords は、探しているキーワードの複数行のテキスト ボックスです。txtPatterns は txtKeywords と同じですが、正規表現パターン用です。
これは、C# Grep に対する私自身のちょっとした実験です。
private List<Tuple<String, Int32, String>> ScanDocuments2()
{
Regex searchPattern = new Regex(@"$(?<=\.(" + txtFilePattern.Text + "))", RegexOptions.IgnoreCase);
string[] keywordtext = txtKeywords.Lines;
List<string> keywords = new List<string>();
List<Regex> patterns = new List<Regex>();
for (int i = 0; i < keywordtext.Length; i++)
{
if (keywordtext[i].Length > 0)
{
keywords.Add(keywordtext[i]);
}
}
string[] patterntext = txtPatterns.Lines;
for (int j = 0; j < patterntext.Length; j++)
{
if (patterntext[j].Length > 0)
{
patterns.Add(new Regex(patterntext[j]));
}
}
try
{
var files = Directory.EnumerateFiles(txtSelectedDirectory.Text, "*.*", SearchOption.AllDirectories).Where(f => searchPattern.IsMatch(f));
//fileCount = files.Count();
var lines = files.Aggregate(
new List<Tuple<String, Int32, String>>(),
(accumulator, file) =>
{
fileCount++;
using (var reader = new StreamReader(file))
{
var counter = 0;
String line;
while ((line = reader.ReadLine()) != null)
{
if (keywords.Any(keyword => line.ToLower().Contains(keyword.ToLower())) || patterns.Any(pattern => pattern.IsMatch(line)))
{
//cleans up the file path for grid
string tmpfile = file.Replace(txtSelectedDirectory.Text, "..");
accumulator.Add(Tuple.Create(tmpfile, counter, line));
}
counter++;
}
}
return accumulator;
},
accumulator => accumulator
);
return lines;
}
catch (UnauthorizedAccessException UAEx)
{
Console.WriteLine(UAEx.Message);
throw UAEx;
}
catch (PathTooLongException PathEx)
{
Console.WriteLine(PathEx.Message);
throw PathEx;
}
}
問題は、どのキーワードまたはパターンが返されるタプルに一致したかを判断するにはどうすればよいかということです。