Привет, я хочу сделать что-то вроде метаязыка, который анализируется и кэшируется, чтобы быть более производительным. Поэтому мне нужно иметь возможность разбирать метакод на объекты или массивы.
Идентификатор начала: {
Конечный идентификатор: }
Вы можете перемещаться по объектам с помощью точки (.), но вы также можете выполнять арифметические/логические/реляционные операции.
Вот пример того, как выглядит метаязык:
- {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/
Заранее спасибо!
Ответ 1 · рейтинг 1 · Daniel Vandersluis
Нетривиально анализировать неопределенное количество совпадающих фигурных скобок с помощью регулярных выражений, потому что в общем случае вы либо найдете слишком много совпадений, либо слишком мало.
Например, рассмотрите 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 разрешает рекурсивные регулярные выражения, но вы собираетесь чтобы получить очень сложный узор, если вы пойдете по этому пути.
Лучшим решением, на мой взгляд, было бы создание токенизатора (который мог бы работать на регулярном выражении), чтобы превратить ваш текст в массив токенов, которые затем можно будет проанализировать.