Разработка на коленке

"тут должна быть красивая цитата о программировании"

Как я выбирал между re и grep

2014-02-28 18:00

Было время, когда задачи решались первым же (и самое главное "гениальным") способом, пришедшим в голову. Теперь всё несколько иначе. Возникла у меня задача: человеку показывают в веб-интерфейсе список файлов, человек вводит в поле ввода фразу, и нужно найти, в каких файлах эта фраза есть. Я не знаю, как бы я решал эту задачу раньше, но сейчас было примерно так:

  • нужно найти фразу... хм;
  • можно сделать через in в каждой строке, можно сделать через регулярки (import re), а можно вызвать grep из питоновского кода;
  • многострочный поиск не нужен, в задаче от него толку немного, значит re со своим re.MULTILINE избыточен;
  • in недостаточен, потому что нужна возможность вводить простейшие регулярки
  • значит re vs grep;
  • вызывать внешний процесс боязно, вдруг отработает что-то не так и исключение не поймаем?
  • а вдруг кто захочет обойти питоновское экранирование и ввести rm -rf?
  • не, хакеров у нас нет, доступ к функции приложения у нескольких человек, да и питон не под рутом;
  • а если регулярка сложная и re, который работает как НКА, будет долго жужжать?
  • а если re съест много памяти? grep же всю память освободит, как только завершится;
  • ещё у grep ДКА, т.е. скорость поиска зависит только от величины текста;
  • а если вывод grep будет большой и много памяти уйдёт на это? ведь вывод нужно не просто отдать, как есть а ещё и переформатировать;
  • но ровно столько же вывода отдаст и re;
  • т.е у grep преимущество, потому что ДКА и память точно освободится, но недостаток в том, что процесс внешний;
  • а как будут передаваться регулярки со спецсимволами, например \w+? нормально будут передаваться, только синтаксис греповский \w\+;
  • преимущества grep в данном случае важнее, чем недостатки, а если требования изменятся, то перепишу;
  • берём subprocess.Popen(['grep', '-rin', what, where]).

После этого пишу 15 строк кода, над которыми дольше думал, чем писал их.