Регулярное выражение для вложенных тегов

Я разрабатываю расширение, чтобы выделить некоторый настраиваемый код сценария, и мне нужно регулярное выражение, которое может захватывать текст между <> (включая внешние теги и вложенные)

пример ссылки: https://regex101.com/r/7AkKRU/1

или же

небольшая демонстрация (контент, который необходимо захватить, будет прокомментирован):

IF !(<isempty <ctag.add_sub>>) //<isempty <ctag.add_sub>>
    if (<ctag0.add_sub_page>) //<ctag0.add_sub_page>
        local.index=<eval 14*<ctag.add_sub_page>> //<eval 14*<ctag.add_sub_page>>
    endif
    local.sub=<LDB.Row.<dctag.add_sub>.subsection> //<LDB.Row.<dctag.add_sub>.subsection>
    LDB.query "SELECT rowid,description FROM <ctag.add_mode> WHERE subsection = '<local.sub>'" //<ctag.add_mode> <local.sub>
    dtext 516 45 0480 Page (<eval <ctag0.add_sub_page>+1>/<eval (<ldb.row.numrows>/14)+1>) //<eval <ctag0.add_sub_page>+1> <eval (<ldb.row.numrows>/14)+1>
    for 0 13
        local.desc=<ldb.row.<dlocal.num>.description> //<ldb.row.<dlocal.num>.description>
        if (<dlocal.num>< <ldb.row.numrows>) //<dlocal.num> <ldb.row.numrows>
            button 760 <dlocal.dy> 4005 4007 1 0 <eval 100000+<dlocal.rowid>> //<dlocal.dy> <eval 100000+<dlocal.rowid>>
        endif
    endfor
    IF (<ldb.row.numrows> > <eval <local.index>+14>) //<ldb.row.numrows> <eval <local.index>+14>
    endif       
endif

На данный момент у меня есть следующее регулярное выражение (не помню, откуда я скопировал, извините):

(?=\<)(?:(?=.*?\<(?!.*?\1)(.*\>(?!.*\2).*))(?=.*?\>(?!.*?\2)(.*)).)+?.*?(?=\1)[^\<]*(?=\2$)

Работает нормально, но когда> является последним элементом строки, он захватывает дополнительный контент.

ОБНОВИТЬ: это было помечено как дублированное, но это не то же самое (хотя они очень похожи), это не для HTML / XHTML / XML, моя проблема в том, что тег не назван (контент), как на этих языках, я должен соответствуют только тегам <>.

Не пишите регулярное выражение для соответствия коду. Это применимо к HTML точно так же, как и к вашему пользовательскому коду скрипта. Кстати, что это за язык? И на каком языке вы это обрабатываете?

Tomalak 10.07.2018 07:13

Это для скриптов сферного сервера (эмулятор Ultima Online). Кстати, это регулярное выражение, которое я использую сейчас, и оно отлично работает \<(.+?)[\w\S\>]*\>

Fabio Pinto 11.07.2018 15:01

Вы можете сделать это короче: <.+?[\S>]*>. Тем не менее, я бы сказал, что он не работает отлично - он не работает с такими вещами, как <eval <local.index> + 14>, которые, как я полагаю, являются законными?

Tomalak 11.07.2018 15:18

Вы правы, я не заметил, что, поскольку файл, который я использую в качестве тестового примера, всегда написан как <eval <local.index>+14>

Fabio Pinto 11.07.2018 19:06

Да ... это как раз проблема с использованием регулярных выражений для таких задач - они не имеют понятия вложенности. Любой язык, поддерживающий вложенные структуры (например, вложенные наборы < и > или вложенные наборы if и endif и т. д.), Сложнее, чем может обрабатывать регулярное выражение. Вы не сможете написать регулярное выражение, которое может правильно анализировать этот код, это невозможно на фундаментальном уровне. Некоторые диалекты регулярных выражений (в первую очередь pcre) имеют расширения, которые мощь могут помочь вам получить что-то достаточно хорошее, но это зависит от того, какой диалект регулярного выражения вы можете здесь использовать.

Tomalak 11.07.2018 20:38

В более общем плане вам нужно будет использовать (или написать) синтаксический анализатор, который может понимать этот язык сценариев, чтобы вы могли выбирать нужные элементы из синтаксического дерева, которое генерирует синтаксический анализатор. Очень дешевая версия была бы как "перебрать все символы в скрипте. когда вы видите <, увеличивайте счетчик и запомните текущую позицию строки. когда вы видите другой <, увеличивайте счетчик и двигайтесь дальше. Когда вы видите >, уменьшайте счетчик. Когда счетчик достигает 0, вырезать строку из запомненной позиции до текущей позиции и вывести эту подстроку. repeat. "

Tomalak 11.07.2018 20:45
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
24
0

Другие вопросы по теме