findall / finditer в потоке? - PullRequest
       2

findall / finditer в потоке?

4 голосов
/ 19 марта 2012

Есть ли способ получить функциональность re.findall или, что еще лучше, re.finditer, примененную к потоку (т. Е. Файловый дескриптор, открытый для чтения)?

Обратите внимание, что я не при условии, что сопоставляемый шаблон полностью содержится в одной строке ввода (т. Е. Разрешены многострочные шаблоны).Также я не предполагаю максимальной длины совпадения.

Это правда, что на этом уровне общности можно указать регулярное выражение, которое потребовало бы, чтобы механизм регулярных выражений имел доступ ко всей строке (например, r'(?sm).*'), и, конечно, этоозначает необходимость считывания всего файла в память, но в данный момент меня не касается этот наихудший сценарий.В конце концов, вполне возможно написать регулярные выражения с многострочным соответствием, которые не требуют чтения всего файла в память.

Возможно ли получить доступ к базовому автомату (иличто используется внутри) из скомпилированного регулярного выражения, чтобы передать ему поток символов?

Спасибо!

Редактировать: добавлены пояснения относительно многострочных шаблонов и длин совпадений, в ответ на Тима Пицкераи ответы rplnt.

Ответы [ 2 ]

3 голосов
/ 19 марта 2012

Это возможно, если вы знаете, что совпадение с регулярным выражением никогда не охватит новую строку.

Тогда вы можете просто сделать

for line in file:
    result = re.finditer(regex, line)
    # do something...

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

Edit:

Теоретически это возможно сделать. Механизм регулярных выражений должен был бы проверить, достигает ли в какой-либо момент в ходе попытки сопоставления конец текущей считываемой части потока, и, если он это делает, читать дальше (возможно, до EOF). Но движок Python этого не делает.

Редактировать 2:

Я взглянул на Python stdlib re.py и связанные с ним модули. Фактическая генерация объекта регулярного выражения, включая его метод .match() и другие, выполняется в расширении C. Таким образом, вы не можете получить к нему доступ и установить его для обработки потоков, если только вы не отредактируете исходники C напрямую и не создадите свою собственную версию Python.

2 голосов
/ 19 марта 2012

Можно было бы реализовать по регулярному выражению с известной максимальной длиной.Либо нет + / *, либо те, где вы знаете максимальное количество повторений.Если вы знаете это, вы можете читать файлы по частям и сопоставлять их, получая результат.Вы также можете запустить регулярное выражение на перекрывающемся фрагменте, который будет охватывать случай, когда регулярное выражение будет соответствовать, но остановлено к концу строки.* Просто идея, но я надеюсь, что вы получите то, чего я пытаюсь достичь.Вы должны учитывать, что файл (поток) может закончиться и в некоторых других случаях.Но я думаю, что это можно сделать (если длина регулярного выражения ограничена (известна)).

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