Как делают меня re.search или re.match на целом файле, не читая все это в память?

На мой взгляд, лучший способ вообще запретить SQL-инъекцию в вашем PHP-приложении (или любом веб-приложении, если на то пошло) - это думать о архитектуре вашего приложения. Если единственный способ защитить от SQL-инъекции - не забудьте использовать специальный метод или функцию, которая делает The Right Thing каждый раз, когда вы разговариваете с базой данных, вы делаете это неправильно. Таким образом, это просто вопрос времени, пока вы не забудете правильно отформатировать свой запрос в какой-то момент вашего кода.

Принятие шаблона MVC и структуры, такой как CakePHP или CodeIgniter - это, вероятно, правильный путь: общие задачи, такие как создание безопасных запросов к базе данных, были решены и централизованно реализованы в таких рамках. Они помогают организовать ваше веб-приложение разумным образом и заставляют вас больше думать о загрузке и сохранении объектов, а не о безопасном построении отдельных SQL-запросов.

30
задан Mark Harrison 11 May 2016 в 05:58
поделиться

6 ответов

Можно использовать mmap для отображения файла на память. К содержанию файла можно тогда получить доступ как нормальная строка:

import re, mmap

with open('/var/log/error.log', 'r+') as f:
  data = mmap.mmap(f.fileno(), 0)
  mo = re.search('error: (.*)', data)
  if mo:
    print "found error", mo.group(1)

Это также работает на большие файлы, содержание файла внутренне загружается из диска по мере необходимости.

60
ответ дан sth 27 November 2019 в 23:29
поделиться

Это зависит от файла и regex. Лучшая вещь, которую Вы могли сделать, будет состоять в том, чтобы считать файл в линию за линией, но если это не работает на Вашу ситуацию, тогда мог бы застрять с получением по запросу целого файла в память.

Позволяет, говорят, например, что это - Ваш файл:

Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Ut fringilla pede blandit
eros sagittis viverra. Curabitur facilisis
urna ABC elementum lacus molestie aliquet.
Vestibulum lobortis semper risus. Etiam
sollicitudin. Vivamus posuere mauris eu
nulla. Nunc nisi. Curabitur fringilla fringilla
elit. Nullam feugiat, metus et suscipit
fermentum, mauris ipsum blandit purus,
non vehicula purus felis sit amet tortor.
Vestibulum odio. Mauris dapibus ultricies
metus. Cras XYZ eu lectus. Cras elit turpis,
ultrices nec, commodo eu, sodales non, erat.
Quisque accumsan, nunc nec porttitor vulputate,
erat dolor suscipit quam, a tristique justo
turpis at erat.

И это было Вашим regex:

consectetur(?=\sadipiscing)

Теперь этот regex использование положительное предвидение и будет только соответствовать строке "consectetur", если это будет сразу сопровождаться каким-либо whitepace символом и затем строкой "adipiscing".

Так в этом примере необходимо было бы считать целый файл в память, потому что regex в зависимости от всего файла, проанализированного как единственная строка. Это - один из многих примеров, которые потребовали бы, чтобы у Вас была своя вся строка в памяти для конкретного regex для работы.

я предполагаю, что неудачный ответ - то, что все это зависит от Вашей ситуации.

5
ответ дан Andrew Hare 27 November 2019 в 23:29
поделиться

Если это - грандиозное предприятие и стоимостью в некоторое усилие, можно преобразовать регулярное выражение в конечный автомат, который читает файл. FSM может иметь O (n) сложность, что означает, что это будет намного быстрее, поскольку размер файла становится большим.

Вы будете в состоянии эффективно соответствовать шаблонам, которые охватывают строки в файлах, слишком больших для умещений в памяти.

Вот два места, которые описывают алгоритм для преобразования регулярного выражения к FSM:

2
ответ дан Mark Harrison 27 November 2019 в 23:29
поделиться

Это - один путь:

import re

REGEX = '\d+'

with open('/tmp/workfile', 'r') as f:
      for line in f:
          print re.match(REGEX,line)
  1. с оператором в python 2.5 берет автоматического закрытия файла. Следовательно Вы не должны волноваться об этом.
  2. итератор по объекту файла является эффективной памятью. это - он, привычка считала больше, чем строка памяти в установленный срок.
  3. , Но отодвижение этого подхода то, что потребовалось бы много времени для огромных файлов.

Другой подход, который происходит по моему мнению, должен использовать чтение (размер) и file.seek (смещение) метод, который считает часть размера файла за один раз.

import re

REGEX = '\d+'

with open('/tmp/workfile', 'r') as f:
      filesize = f.size()
      part = filesize / 10 # a suitable size that you can determine ahead or in the prog.
      position = 0 
      while position <= filesize: 
          content = f.read(part)
          print re.match(REGEX,content)
          position = position + part
          f.seek(position)

можно также объединить эти два там, можно создать генератор, который возвратил бы содержание определенные байты в то время и выполнил бы итерации через то содержание для проверки regex. Этот IMO был бы хорошим подходом.

2
ответ дан sth 27 November 2019 в 23:29
поделиться

Для однострочных шаблонов можно выполнить итерации по строкам файла, но для многострочных шаблонов, необходимо будет считать все (или часть, но это будет трудно отслеживать) файла в память.

0
ответ дан sykora 27 November 2019 в 23:29
поделиться

Откройте файл и выполните итерации по строкам.

fd = open('myfile')
for line in fd:
    if re.match(...,line)
        print line
0
ответ дан Mark Harrison 27 November 2019 в 23:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: