Python: Regex фиксированной длины требуется?

У меня есть это регулярное выражение, которое использует прогнозирование вперед и назад:

import re
re.compile("<!inc\((?=.*?\)!>)|(?<=<!inc\(.*?)\)!>")

Я пытаюсь перенести его с C# на Python, но постоянно получаю сообщение об ошибке

look-behind requires fixed-width pattern

Можно ли переписать это на Python без потери смысла?

Идея состоит в том, чтобы это соответствовало чему-то вроде

<!inc(C:\My Documents\file.jpg)!>

Обновить

Я использую обходные пути для анализа HTTP-текста, который я изменил

body = r"""------abc
Content-Disposition: form-data; name="upfile"; filename="file.txt"
Content-Type: text/plain

<!inc(C:\Temp\file.txt)!>
------abc
Content-Disposition: form-data; name="upfile2"; filename="pic.png"
Content-Type: image/png

<!inc(C:\Temp\pic.png)!>
------abc
Content-Disposition: form-data; name="note"

this is a note
------abc--
"""

multiparts = re.compile(...).split(body)

Я хочу просто получить путь к файлу и другой текст, когда я делю разделение и не нужно удалять открывающие и закрывающие теги

Краткость кода важна, но я открыт для изменения <!inc( формат, если это делает регулярное выражение выполнимым.

3 ответа

Решение

Для путей + "все" в одном и том же массиве просто разделите на открывающий и закрывающий тег:

import re
p = re.compile(r'''<!inc\(|\)!>''')
awesome = p.split(body)

Вы говорите, что вы гибки в закрывающих тегах, если )!> может произойти в другом месте кода, вы можете рассмотреть возможность изменения этого закрывающего тега на что-то вроде )!/inc> (или что-нибудь, пока это уникально).

Смотри, беги.

Из документации:

(?<!...)

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

(?<=...)

Соответствует, если текущей позиции в строке предшествует совпадение для..., которое заканчивается в текущей позиции. Это называется положительным взглядом за утверждением. (?<=abc)def найдет совпадение в abcdef, поскольку lookbehind создаст резервную копию 3 символов и проверит, соответствует ли содержащийся шаблон. Содержащийся шаблон должен соответствовать только строкам некоторой фиксированной длины, что означает, что abc или a | b разрешены, а a* и a{3,4} - нет. Обратите внимание, что шаблоны, которые начинаются с положительных утверждений за задним числом, не будут совпадать в начале искомой строки; вы, скорее всего, захотите использовать функцию search(), а не функцию match():

Акцент мой. Нет, я не думаю, что вы можете перенести его на Python в его текущей форме.

import re

pat = re.compile("\<\!inc\((.*?)\)\!\>")

f = pat.match(r"<!inc(C:\My Documents\file.jpg)!>").group(1)

результаты в f == 'C:\My Documents\file.jpg'

В ответ на Джон Клементс:

print re.escape("<!inc(filename)!>")

результаты в

\<\!inc\(filename\)\!\>

Заключение: re.escape Кажется, они думают, что их нужно сбежать.

Другие вопросы по тегам