Поиск регулярных выражений в файлах с использованием Java - PullRequest
1 голос
/ 07 февраля 2012

То, что я здесь спрашиваю, должно быть довольно распространенным, но я намерен найти наилучший из возможных способов сделать это.

  • У меня есть список файлов (скажем, n) в каталоге - все из которых имеют были классифицированы по расширениям.
  • У меня есть CSV-файл, содержащий шаблоны Regex (скажем, m), который я хочу найти во всех этих файлах определенного типа.
  • Я хочу получить окончательный вывод, в котором у меня есть шаблон Regex, имя файла, строка и номер строки в списке.

Вот несколько вопросов о том, как мне к этому подойти:

  1. Есть ли способ избежать м * п операций?
  2. Что быстрее - чтение файлов, буферизация содержимого и сохранение каждой строки, скажем, в массиве, перед поиском всех выражений регулярного выражения, или я должен взять шаблон регулярного выражения, прочитать файл построчно и выполнить поиск по мере разбора, не используя память?
  3. Я полагаю, что операции чтения / записи являются наиболее сложными - поэтому я хочу, чтобы чтения 'n + 1' (файлы, csv) и только одна запись выполнялись в самом конце. Верно ли мое предположение и подход?
  4. Массивы, списки, хеш-карты, что-то еще - какие-либо предложения о том, как лучше всего выполнить задачу? Я думаю, что анализ файлов будет ключом к эффективности?
  5. Какие-нибудь "необычные" API-интерфейсы Java, которые я могу использовать, значительно сокращают код?

Я ценю любые идеи и помощь по этому вопросу.

.

1 Ответ

4 голосов
/ 07 февраля 2012

Сначала напишите простое рабочее решение, , а затем оптимизируйте его. Тем не менее, я думаю, что вы могли бы сделать что-то вроде:

  • Создайте составное регулярное выражение из каждого отдельного регулярного выражения, которое вы ищете. Если они не используют шаблоны захвата, я подозреваю, что вы могли бы просто сделать что-то вроде "(regex1)|(regex2)|(regex3)", и это было бы правильно. Я не уверен, хотя - мне никогда не было ясно, как работают группы захвата регулярных выражений, когда они находятся в разных | ветвях.
  • Используйте Pattern.compile(regexString) для предварительной компиляции регулярного выражения, чтобы оно не перестраивалось более одного раза.
  • Используйте Guava's Files.toString(File, Charset), чтобы просто хлебать каждый файл одновременно. Если вы заинтересованы в том, чтобы делать это построчно, используйте Files.readLines(File, Charset), чтобы получить List<String>. Вы могли бы даже использовать полномасштабный Files.readLines(File, Charset, LineProcessor) на основе обратного вызова, чтобы избежать одновременного хранения всего файла в памяти.
  • Используйте скомпилированный Pattern для сопоставления с целевым файлом - вам, вероятно, потребуется использовать Matcher, чтобы определить, где было точное совпадение и какой шаблон был сопоставлен.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...