Разбор вложенных структур в PHP с помощью preg_match

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

Идентификатор начала: {

Конечный идентификатор: }

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

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

  • {mySelf.mother.job.jobName}

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

  • {mySelf.{myObj.{keys["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/

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


person Christian Beikov    schedule 05.08.2010    source источник
comment
Если вам нужна помощь с регулярным выражением, пожалуйста, дайте несколько примеров до и после того, какое именно преобразование вы хотите. (Или сопоставьте [то, что вы хотите извлечь], как в этом случае)   -  person zebediah49    schedule 06.08.2010
comment
Вероятно, вам намного лучше написать парсер, просто используйте строки, сопоставляющие их с определенными предопределенными токенами, и действуйте соответственно. Достаточно примеров в Интернете для «написать свой собственный парсер».   -  person Wrikken    schedule 06.08.2010
comment
Вы действительно должны изменить структуру каталогов. Если я даже не могу найти код вашего парсера в течение десяти минут, это должно быть ужасно.   -  person NikiC    schedule 06.08.2010
comment
Не хочу показаться мудаком, но какой в ​​этом смысл? Чтобы использовать этот фреймворк, мне нужно выучить совершенно новый язык, который не похож на PHP или что-то еще, что я видел. Кроме того, это приведет к значительному снижению производительности. Извините, но это кажется бесполезным. Если я хочу написать правильный ООП-код на PHP, я могу (и буду) делать это без изучения нового языка.   -  person NullUserException    schedule 06.08.2010
comment
@NullUserException Первое, что пришло мне в голову, когда я увидел этот вопрос, это BobX .   -  person Daniel Vandersluis    schedule 06.08.2010
comment
Он будет проанализирован во время компиляции, а затем просто разрешен со значениями времени выполнения. Вот почему я хочу разобрать такое выражение. Библиотека является объектно-ориентированной, поэтому структура каталогов ориентирована на пространства имен, извините, что я забыл опубликовать пакеты, см. blaze\web\el для ELResolver и blazeServer\view\IndexView для представления, использующего класс Expression. Языком будет PHP для серверной части и XML со схемой для внешнего интерфейса. Проблем с производительностью не будет, поскольку для правильной работы приложение должно быть развернуто на сервере.   -  person Christian Beikov    schedule 06.08.2010


Ответы (2)


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

Например, рассмотрите 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 разрешает рекурсивные регулярные выражения, но вы собираетесь чтобы получить очень сложный узор, если вы пойдете по этому пути.

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

person Daniel Vandersluis    schedule 05.08.2010
comment
Большое спасибо! Я сделал это сейчас с помощью токенизатора на основе регулярных выражений, который использует рекурсию для обнаружения скобок. Кстати, шаблон не очень сложный, но мне приходится рекурсивно вызывать метод, чтобы получить всех дочерних элементов, но это быстро и красиво =D - person Christian Beikov; 05.09.2010

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

person Andreas Linden    schedule 05.08.2010