Использование групп балансировки регулярных выражений для соответствия тегам вложенности
Я пытаюсь использовать регулярные выражения балансировки групп для соответствия вложенности тегов выглядит следующим образом:
some text ...
{list}
nesting loop content
{list}
{list}
{list}
bala ...
{/list}
{/list}
{/list}
{/list}
end
мой экспрессон:
\{(?<NAME>.+?)\}
[^\{\}]*
(
(
\{(?<NAME2>.+?)\}(?<OPEN>)
[^\{\}]*?
)
(
\{\/\<NAME2>\}(?<-OPEN>)
[^\{\}]*?
)
)*
(?(OPEN)(?!))
\{\/\<NAME>\}
моя проблема:
only last 2 level pair can match.
1 ответ
Решение
Как правило, чтобы соответствовать вложенным тегам, вам нужно что-то похожее на:
(?>
\{(?<Open>\w+)\}
|
\{/(?<-Open>\<Open>)\}
|
(?(Open)[^{}]+)
)*
(?(Open)(?!))
Таким образом, вы можете сопоставлять вложенные теги разных типов, что похоже на то, что вы пытаетесь сделать. Например, это будет соответствовать этому:
{list}
nesting loop content
{world}
{list}
{hello}
bala ...
{/hello}
{/list}
{/world}
{/list}
Заметки:
- я использую
(?(Open)[^{}]+)
поэтому мы сопоставляем свободный текст, только если он находится внутри тегов. - Я использую ту же группу для верхнего уровня и внутренних уровней.
Твой был довольно близко. В основном вам не хватает одного чередования между средними группами:
(
\{(?<NAME2>.+?)\}(?<OPEN>)
[^\{\}]*?
)
| # <---- This
(
\{\/\<NAME2>\}(?<-OPEN>)
[^\{\}]*?
)
Тем не менее, вы всегда используете последнее значение $NAME2
, $NAME2
это стек, но вы никогда не извлекаете из него значения, только нажимаете. Это вызывает ошибку: она также будет соответствовать этой строке (что, вероятно, неправильно):
{list} # Set $Name = "world"
nesting loop content
{world} # Set $Name2 = "world"
{world} # Set $Name2 = "world"
{hello} # Set $Name2 = "hello"
bala ...
{/hello} # Match $Name2 ("hello")
{/hello} # Match $Name2 ("hello")
{/hello} # Match $Name2 ("hello")
{/list} # Match $Name ("list")
Смотрите также: