2010-11-05 3 views
0

Я пытаюсь выработать строку регулярного выражения PCRE для сопоставления и записи строк переменной длины для использования в моем приложении PHP. Я бы хотел (если бы правдоподобно) выполнять действия в одном синтаксическом анализе, но если это кажется наиболее разумным для вычисления, я могу разбить его на несколько прогонов, разделенных логикой приложения.Help with Regex (PCRE)

несколькими примеров строк, которые могут содержаться в гораздо больших блоках текста:

{{ var:myVar }} 
{{ component:myComponent}} 
{{ var:myVar modifier:function[arg1|arg2] }} 
{{ region:myRegion modifier:function[arg1|arg2] modifier:function[arg1] }} 

Как вы можете видеть, может быть значительно отличается другом от целевых строк. Обобщенная:

{{ type:name modifierType:modifierName[arg1|arg2|...] }} 
  • разделителей {{ и }}.
  • Действительный type или name выражается как [a-z_][a-z0-9_]*; Будет только одна пара type:name, и она появится в первую очередь.
  • Действительный modifierType или modifierName выражается как [a-z_][a-z0-9_]; За номером modifierName следует список аргументов одного или более аргументов в квадратных скобках, [ и ]. Список аргументов делится на трубы |. Там может быть нуль или больше modifierType:modifierName[argumentList] комплектов.
  • Все части строки разделяются один или более-пробельных символов \s+

В любом случае, соответствующие наборы, которые только {{ type:name }} достаточно легко, но я не могу понять способ эффективно захватить переменную -length. Для простой пары типа/имени, я использую следующую регистронезависимым/свободный Разнос строку:

'% {{ \s+ (?<type>var|component|region):(?<name>[a-z_][a-z0-9_]*) \s+ }} %ix' 

Я, вероятно, собираюсь поменять тип-список для общего буквенно-цифрового захвата строки для Форвард совместимость, но сейчас это работает.

Таким образом, любые предложения по захватывая как:

{{ component:myComponent }} 
{{ var:myVar format:datetime[Y-m-d] container:h3[class=timestamp|id=main] }} 

ответ

2

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

Захватите главное ({{ something }}), разделите содержимое пробелами, затем выполните цикл и сопоставьте их индивидуально, перетаскивая содержимое в соответствующий скаляр или массив (если вы разрешаете больше модификаторов с одним и тем же префиксом).

+0

Спасибо за ваш быстрый ответ ** Amadan **. У меня было ощущение, что это будет лучший маршрут. Поскольку будет только один экземпляр каждого модификатора (только один «формат», только один «контейнер» и т. Д.), Я думал, что могу писать записи для каждого типа. Тем не менее, я хочу, чтобы все было совместимо с первыми, поэтому я вижу, что лучше всего использовать несколько прогонов, не говоря уже о списках аргументов переменной длины для каждого модификатора. – Dan