findall / finditer в потоке?

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

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

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

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

Благодаря!

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

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

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

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

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

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

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

Изменить 2:

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

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

некоторый псевдо-код (python):

 overlap_tail = '' matched = {} for chunk in file.stream(chunk_size): # calculate chunk_start for result in finditer(match, overlap_tail+chunk): if not chunk_start + result.start() in matched: yield result matched[chunk_start + result.start()] = result # delete old results from dict overlap_tail = chunk[-max_re_len:] 

Просто идея, но я надеюсь, что вы получите то, что я пытаюсь достичь. Вам нужно будет подумать, что файл (поток) может закончиться и некоторые другие случаи. Но я думаю, что это можно сделать (если длина регулярного выражения ограничена (известна)).