У меня очень длинная строка с вложенными циклами. Я хочу извлечь шаблон в этом.
String_Text:
some random texts......
........................
........................
{{info .................
.....texts..............
...{{ some text }}...... // nested parenthesis 1
........................
...{{ some text }}...... // nested parenthesis 2
........................
}} // End of topmost parenthesis
........................
..again some random text
........................
........................ // can also contain {{ }}
......End of string.
Я хочу извлечь весь текст между верхней скобкой, т.е.
Extracted_string:
info .................
.....texts..............
...{{ some text }}...... // nested parenthesis 1
........................
...{{ some text }}...... // nested parenthesis 2
........................
Шаблон:
1.) начинается с { и за ним может следовать любое число {.
2.) После этого может быть любое количество пробелов.
3.) Первое слово после этого обязательно информация.
4.) Извлеките до тех пор, пока этот кронштейн не будет закрыт.
Что до сих пор пробовали:
re.findall(r'\{+[^\S\r\n]*info\s*(.*(?:\r?\n.*)*)\}+')
Я знаю, что это неправильно, так как это происходит, это найти последний экземпляр } в строке. Может ли кто-нибудь помочь мне в извлечении текста между этими скобками? ТИА
Работа вокруг шаблона может быть той, которая соответствует строке, начинающейся с {{info
а затем соответствует любым символам 0+ как можно меньше вплоть до строки с помощью }}
на ней:
re.findall(r'(?sm)^{{[^\S\r\n]*info\s*(.*?)^}}$', s)
См. Демо-версию regex.
подробности
(?sm)
- re.DOTALL
(теперь .
совпадает с символом новой строки) и re.MULTILINE
(^
теперь соответствует линии начали и $
соответствуют окончанию линии позиции) флаги^
- начало строки{{
- a {{
подстрока[^\S\r\n]*
- 0+ горизонтальные пробелыinfo
- подстрока\s*
- 0+ пробелы(.*?)
- Группа 1: любые 0+ символы, как можно меньше^}}$
- начало строки, }}
и конец строки.Вам нужно использовать рекурсивный подход:
{
((?:[^{}]|(?R))*)
}
Это поддерживается только новым модулем regex
, см. Демонстрацию на regex101.com.
{{info...}}
. И вы не можете просто добавить info
после первого {
in {((?:[^{}]|(?R))*)}
.
В этом ответе объясняется, как это сделать с рекурсией (хотя и для круглых скобок, но легко адаптируемым), однако, лично, я просто написал бы это с помощью цикла while:
b = 1
i = si = s.index('{')
i += 1
while b:
if s[i] == '{': b += 1
elif s[i] == '}': b -=1
i += 1
ss = s[si:i]
где, с вашей строкой, определенной как: s
, дает подстроку, ss
, as:
>>> print(ss)
{{info .................
.....texts..............
...{{ some text }}...... // nested parenthesis 1
........................
...{{ some text }}...... // nested parenthesis 2
........................
}}
}}
которые находятся на отдельной строке? Какre.findall(r'(?sm)^{{[^\S\r\n]*info\s*(.*?)^}}$', s)
?