Xpoint
   [напомнить пароль]

Nested Regexp

Метки: [без меток]
2008-06-01 20:57:48 [обр] Bohdan[досье]

...и жил он себе, поживал, в серверной пахал, да пиво попивал, пока не пршел злой царь, и не поставил такую задачу...

Имя тому велос... той задаче - template engine.

Имеется строка:

$str = "
{foo aaa}
    text_1
{endfoo}
{foo bbb} text_2 {endfoo}
{foo ccc}
     before, {foo BAR} BAZ {endfoo}, after.
{endfoo}
";

Имеется регулярное выражение:

$str =~ s/
   {              # начало тега
      (\S+)       # имя (foo)                $1
      \b(.*?)     # параметры                $2
   }              # конец тега
   (.+?)          # "внутреннее содержимое"  $3
   {(             # закрывающий парный тег
      end(?:\1)   # end$1 (endfoo)           $4
   )}   
/
   print "content of $1 ($2 ): $3 \n";
/xegs;
# extended, expression, global match, threat as single line

Задача - получить на выходе:

content of foo ( aaa ): text_1
content of foo ( bbb ): text_2
content of foo ( ccc ): before, {foo BAR} BAZ {endfoo}, after.

в то время как на самом деле получаем:

...
before, {foo BAR} BAZ

, т.е. регулярное выражение ловит первый попавшийся {endfoo}, что естественно. Надо таки как-то "ловить" парность/вложенность тегов, вопрос в том, как?

Если (.+?) заменить на (.+), то в $3 попадет вообще всё, вплоть до последнего {endfoo}

Чувствую, что решение где-то на поверхности, перечитал уже все маны по регекспам, но так и не сообразил, как сделать правильно.

Попытки использовать Code evaluation expressions aka (?{ ... code block ...}) возвенчались только полной капитуляцией и паникой Perl (v5.8.7):
panic: top_env

Вот, собственно, и вся история. Может ли кто с этим помочь, или может уже кто сотворил этот велосипед? TT и Mason непосредственное начальство использовать не велело. Как быть?

спустя 6 часов [обр] Роман Чемисов(16/350)[досье]
Bohdan[досье]
Эта задачка не для регулярных выражений. Читайте Lexing Your Data
Powered by POEM™ Engine Copyright © 2002-2005