Разбор вложенных структур в PHP с помощью preg_match - PullRequest
0 голосов
/ 06 августа 2010

Здравствуйте, я хочу создать что-то вроде метаязыка, который будет анализироваться и кэшироваться для большей производительности. Поэтому мне нужно иметь возможность разбирать метакод на объекты или массивы.

Startidentifier: {

Endidentifier:}

Вы можете перемещаться по объектам с точкой (.), Но вы также можете выполнять арифметические / логические / реляционные операции.

Вот пример того, как выглядит мета-язык:

  • {mySelf.mother.job.jobName}

или вложенный

  • {сам. {myObj. {[ "ключи" ObjProps] [0]}. personAttribute.first}} .size

или с операциями

  • {obj.val * (otherObj.intVal + myObj.longVal) == 1200}

или более логично

  • {obj.condition ==! MyObj.otherCondition}

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

например. «Здравствуйте, {myObj.name}! Как поживаете {myObj.type}?».

Также есть возможность сократить, если нравится (условие)? (true-case): (false-case) было бы неплохо, но я понятия не имею, как разобрать все эти вещи. В настоящее время я работаю с циклами с некоторым регулярным выражением, но, возможно, было бы быстрее и еще более легко обслуживаться, если бы у меня было больше регулярных выражений.

Так кто-нибудь может дать мне несколько советов или хочет помочь мне? Может быть, посетите сайт проекта, чтобы понять, для чего мне это нужно: http://sourceforge.net/projects/blazeframework/

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 06 августа 2010

Нетрудно проанализировать неопределенное количество совпадающих фигурных скобок с помощью регулярных выражений, потому что, как правило, либо вы будете соответствовать слишком много или слишком мало.

Например, рассмотрим Hello {myObj.name}! {mySelf.{myObj.{keys["ObjProps"][0]}.personAttribute.first}.size}?, чтобы использовать два примера из вашего ввода в одной строке:

Если вы используете первое регулярное выражение, которое, вероятно, приходит на ум \{.*\} для сопоставления фигурных скобок, вы получите одно совпадение: {myObj.name}! {mySelf.{myObj.{keys["ObjProps"][0]}.personAttribute.first}.size} Это потому, что по умолчанию регулярные выражения жадные и будут соответствовать как можно больше.

Оттуда мы можем попытаться использовать не жадный шаблон \{.*?\}, который будет как можно меньше совпадать между открывающей и закрывающей скобкой. Используя одну и ту же строку, этот шаблон приведет к двум совпадениям: {myObj.name} и {mySelf.{myObj.{keys["ObjProps"][0]}. Очевидно, что второе не является полным выражением, но нежадный шаблон будет соответствовать как можно меньшему количеству, и это наименьшее соответствие, которое удовлетворяет шаблону.

PCRE действительно допускает рекурсивные регулярные выражения , но вы получите очень сложный шаблон, если вы пойдете по этому маршруту.

Лучшее решение, на мой взгляд, было бы создать токенизатор (который мог бы быть приведен в действие регулярным выражением), чтобы превратить ваш текст в массив токенов, которые затем могут быть проанализированы.

0 голосов
/ 06 августа 2010

возможно взгляните на флаг PREG_OFFSET_CAPTURE!?

...