Python regex не поддерживает рекурсию afaik.
РЕДАКТИРОВАТЬ: но в вашем случае это будет работать:
regex = re.compile(r"""
^ # Must start in a newline first
\[(.*?)\] # Get what's enclosed in brackets
\n # only capture bracket if a newline is next
([^\[]*) # stop reading at opening bracket
""", re.MULTILINE | re.VERBOSE)
РЕДАКТИРОВАТЬ 2: да, это не работает должным образом.
import re
regex = re.compile(r"""
(?:^|\n)\[ # tag's opening bracket
([^\]\n]*) # 1. text between brackets
\]\n # tag's closing bracket
(.*?) # 2. text between the tags
(?=\n\[[^\]\n]*\]\n|$) # until tag or end of string but don't consume it
""", re.DOTALL | re.VERBOSE)
haystack = """[tag1]
this is captured [not a tag[
but this is suppose to be captured too!
[another non-tag
[tag2]
help me
write a better RE[[[]
"""
print regex.findall(haystack)
Хотя я согласен с viraptor. Regex - это круто, но вы не можете проверить ваш файл на наличие ошибок. Гибрид что ли? : P
tag_re = re.compile(r'^\[([^\]\n]*)\]$', re.MULTILINE)
tags = list(tag_re.finditer(haystack))
result = {}
for (mo1, mo2) in zip(tags[:-1], tags[1:]):
result[mo1.group(1)] = haystack[mo1.end(1)+1:mo2.start(1)-1].strip()
result[mo2.group(1)] = haystack[mo2.end(1)+1:].strip()
print result
РЕДАКТИРОВАТЬ 3: Это потому, что символ ^
означает отрицательное совпадение только внутри [^squarebrackets]
. В любом другом месте это означает начало строки (или начало строки с re.MULTILINE
). Нет хорошего способа найти отрицательное соответствие в регулярном выражении, только символ.