Python: исправлено исправление длины Regex?
У меня есть это регулярное выражение, которое использует форвардный и обратный взгляд вперед:
import re
re.compile("<!inc\((?=.*?\)!>)|(?<=<!inc\(.*?)\)!>")
Я пытаюсь перенести его с С# на 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(
, если он делает регулярное выражение выполнимым.
Ответы
Ответ 1
Для путей + "все" в том же массиве просто разделите тег открытия и закрытия:
import re
p = re.compile(r'''<!inc\(|\)!>''')
awesome = p.split(body)
Вы говорите, что вы гибки в закрывающих тегах, если )!>
может встречаться в другом месте кода, вы можете захотеть изменить этот закрывающий тег на что-то вроде )!/inc>
(или что-нибудь, если оно уникально).
Посмотрите, как он работает.
Ответ 2
Из документации:
(?<!...)
Соответствует, если текущая позиция в строке не предшествует совпадению для... Это называется отрицательным утверждением lookbehind. Подобно положительным утверждениям lookbehind, содержащийся шаблон должен соответствовать только строкам некоторой фиксированной длины. Шаблоны, начинающиеся с отрицательных утверждений lookbehind, могут совпадать в начале поиска строки.
(?<=...)
Соответствует, если текущей позиции в строке предшествует совпадение для..., которое заканчивается в текущей позиции. Это называется положительным утверждением lookbehind. (? <= abc) def найдет совпадение в abcdef, так как lookbehind будет поддерживать 3 символа и проверяет соответствие совпадающего шаблона. Содержащийся шаблон должен соответствовать только строкам некоторой фиксированной длины, что означает, что допускаются abc или | b, но a * и a {3,4} - нет. Обратите внимание, что шаблоны, которые начинаются с положительных утверждений lookbehind, не будут совпадать в начале поиска строки; вы скорее всего захотите использовать функцию search(), а не функцию match():
Акцент мой. Нет, я не думаю, что вы можете перенести его на Python в текущую форму.
Ответ 3
import re
pat = re.compile("\<\!inc\((.*?)\)\!\>")
f = pat.match(r"<!inc(C:\My Documents\file.jpg)!>").group(1)
приводит к f == 'C:\My Documents\file.jpg'
В ответ на Jon Clements:
print re.escape("<!inc(filename)!>")
приводит к
\<\!inc\(filename\)\!\>
Заключение: re.escape
похоже, что они должны быть экранированы.