Я хотел правильно сопоставить макросы LaTeX, даже вложенные. См. следующее:
s = r'''
firstline
\lr{secondline\rl{ right-to-left
\lr{nested left-to-right} end RTL }
other text
}
\rl{ last \lr{end line
} end RTL }
'''
Например, в приведенном выше примере я хочу сопоставить макрос \lr
с его содержимым. Я пробовал следующее, но ни один из них не работал правильно:
re.findall(r'(?:\\lr\{.*\})', s, re.DOTALL)
['\\lr{secondline\\rl{ right-to-left\n \\lr{nested left-to-right} end RTL }\n other text\n}\n\\rl{ last \\lr{end line \n} end RTL }']
даже нежадный вариант в данном случае не сработал:
re.findall(r'(?:\\lr\{.*?\})', s, re.DOTALL)
['\\lr{secondline\\rl{ right-to-left\n \\lr{nested left-to-right}',
'\\lr{end line \n}']
Мне нужно какое-то регулярное выражение для правильного сопоставления, похожее на вложенные скобки, здесь у меня есть вложенные фигурные скобки для макросов LaTeX.
Я хотел бы получить следующие совпадения:
['\\lr{secondline\\rl{ right-to-left\n \\lr{nested left-to-right} end RTL }\n other text\n}',
'\\lr{nested left-to-right}',
'\\lr{end line \n}']
Было бы идеально, если бы я знал об уровне вложенности, как показано ниже:
[('\\lr{secondline\\rl{ right-to-left\n \\lr{nested left-to-right} end RTL }\n other text\n}',1)
('\\lr{nested left-to-right}',2)
('\\lr{end line \n}',1)]
@WiktorStribiżew Спасибо. Это замечательно. Как я могу получить все вложенные \lr
?
Пожалуйста, добавьте ожидаемый результат к вопросу.
Пожалуйста, ознакомьтесь с новым изданием.
Я сомневаюсь, что вы можете получить уровень вложенности с помощью регулярных выражений. Итак, все, что я могу предложить, это [x.group() for x in regex.finditer(r'\\lr(\{(?:[^{}]++|(?1))*})', s, overlapped=True)]
, см. демо.
Отлично. Не могли бы вы опубликовать свой код в качестве ответа на мой вопрос?
Разве нельзя сделать это с re?
Нет, re
многого не умеет.
Очень ценю ваше время, чтобы решить мою проблему.
С модулем регулярного выражения PyPi (после его установки с помощью pip install regex
) вы можете использовать
import regex
s = r'''
firstline
\lr{secondline\rl{ right-to-left
\lr{nested left-to-right} end RTL }
other text
}
\rl{ last \lr{end line
} end RTL }
'''
print( [x.group() for x in regex.finditer(r'\\lr(\{(?:[^{}]++|(?1))*})', s, overlapped=True)] )
# => ['\\lr{secondline\\rl{ right-to-left\n \\lr{nested left-to-right} end RTL }\n other text\n}', '\\lr{nested left-to-right}', '\\lr{end line \n}']
См. демонстрация Python и демонстрация регулярных выражений.
Обратите также внимание на параметр overlapped=True
, используемый с regex.finditer
, который позволяет сопоставлять вложенные вхождения.
Подробности:
\\lr
- \lr
строка(\{(?:[^{}]++|(?1))*})
- Группа 1 (определена для ссылки при рекурсии):
\{
- {
символ(?:[^{}]++|(?1))*
- ноль или более повторений[^{}]++
- один или несколько символов, отличных от {
и }
, без возможности повторного сопоставления текста в случае срабатывания поиска с возвратом (т.|
- или(?1)
- рекурсивный шаблон группы 1}
- символ }
.
Если можете
pip install regex
, то можете использовать этот код.