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
Кажется, они думают, что их нужно сбежать.