Самый быстрый способ проверить, существует ли строка в большом количестве файлов - PullRequest
3 голосов
/ 15 февраля 2010

В настоящее время я перебираю где-то между 7000 и 10000 определений текста, размер которых варьируется от 0 до 5000 символов, и я хочу проверить, существует ли конкретная строка в каком-либо из них. Я хочу сделать это где-то в районе 5000 различных определений строк.

В большинстве случаев я просто хочу узнать точное совпадение без учета регистра, однако иногда требуется регулярное выражение, чтобы быть более конкретным. Мне было интересно, будет ли быстрее использовать другую технику «поиска», когда регулярное выражение не требуется.

Уменьшенная версия кода выглядит примерно так.

foreach (string find in stringsiWantToFind)
{
    Regex rx = new Regex(find, RegexOptions.IgnoreCase);
    foreach (String s in listOfText)
        if (rx.IsMatch(s))
            find.FoundIn(s);
}

Я немного перечитал, чтобы понять, упускаю ли я что-нибудь очевидное. Есть несколько предложений по использованию скомпилированных регулярных выражений, однако я не вижу, что это полезно, учитывая «динамическую» природу регулярного выражения.

Я также прочитал интересную статью о CodeProject, так что я только собираюсь взглянуть на использование FastIndexOf, чтобы увидеть, как оно сравнивается по производительности.

Мне просто интересно, есть ли у кого-нибудь какие-либо советы для решения этой проблемы и как можно оптимизировать производительность?

Спасибо

Ответы [ 3 ]

1 голос
/ 15 февраля 2010

Как то так? Создайте одно регулярное выражение, которое содержит все строки, которые вы хотите сопоставить, затем зациклите файлы с этим регулярным выражением. Параметр new Regex, вероятно, неверен, мои знания шаблонов регулярных выражений .net не самые лучшие. Также я пропустил несколько using, чтобы сделать его более читабельным здесь. Вы можете скомпилировать Regex, если это улучшит ситуацию.

Regex rx = new Regex("string1|string2|string3|string5|string-etc", RegexOptions.IgnoreCase);

foreach (string fileName in fileNames)
{
  var fs = new FileStream(fileName.ToString(), FileMode.Open,  FileAccess.ReadWrite, FileShare.ReadWrite);    
  var sr = new StreamReader(fs);    
  var sw = new StreamWriter(fs);

  string readFile = sr.ReadToEnd();
  MatchCollection matches = rx.Matches(readFile );

  foreach (Match match in matches)
  {
    //do stuff
  }
}
0 голосов
/ 15 февраля 2010

Одна хитрость, которая пришла мне в голову, была:

Объедините строки в одну большую, чтобы регулярное выражение работало на глобальном уровне. Это даст вам результаты «найденной строки xx раз», использующей 1 регулярное выражение вместо циклического перебора вашего списка.

Надеюсь, это поможет,

0 голосов
/ 15 февраля 2010

Я бы посмотрел на службу индексирования файлов, такую ​​как Служба индексации MS или Поиск Google Desktop . Эти API позволят вам выполнять поиск по индексам ваших файлов, а не по самим файлам, и работают очень быстро.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...