Intereting Posts
Установка eclipse php в ubuntu PHP: создание относительной даты / времени из временных меток 404 Страница не найдена Запрошенная вами страница не найдена. Код воспламенителя Шифрование / расшифровка RSA, совместимая с Javascript и PHP Оператор PHP = & Почему этот код для центрирования текста в PDF-формате с использованием библиотеки PHP Zend_Pdf не работает? PHP GCM appengine Изменение размера базы64 изображений PHP, функция сжатия которого имеет одинаковый вывод, например mod_deflate? Как проверить, поддерживается ли загрузка файлов на сервере с помощью php PHP, если строка содержит URL, изолировать ее Как разделить сессию входа в Joomla с одного сайта Joomla на один веб-сайт ASP.Net MVC Маршруты Laravel-4 с параметрами вызываются дважды Почему MySQL возвращает те же результаты при использовании RAND () в инструкции SELECT? API-интерфейс Facebook Graph переопределяет явно настройки конфиденциальности

Структура шаблона регулярных выражений, имеющая рекурсию

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

Таким образом, шаблон в основном определяется как:

@param {item} {label}:{text} {labeln}:{textn} 

где labeln и textn – некоторый N экземпляра метки: текстовая группа.

Таким образом, пример будет

 /** * * @param name1 test1:this is text for test1 test2:this is text for test2 * @param name2 test3:this is text for test3 test4:this is text for test4 test5:this is text for test5 * * / 

Теперь, в идеале, я пытаюсь захватить name1 , test1:this is text for test1 и test2:this is text for test2 как группы соответствия. То же самое касается строки name2 . Конечно, может быть еще много примеров name1 а psuedo «именованные параметры» могут варьироваться от одного до многих. + Изменить: в тексте ярлыка не допускается использование колоний, поскольку они зарезервированы как разделители. Ярлык строго буквенно-цифровой, метка, вероятно, будет ограничена a-zA-Z0-9 _, '"-

Первый вопрос … это проблема рекурсии или я неправильно ее оцениваю?

Второй вопрос: возможно ли это, и если да, то как я могу это достичь?

Предисловие:

Для объяснения я решил уточнить ваши «ярлыки», указав их % . Это может быть любой зарезервированный символ или другой шаблон, который помогает очистить ярлык / текст:

 /** * @param variable_a %label:This is variable: a %required:true * @param variable_b %required:false %pattern:/[a-zA-Z:]/ */ 

Проблема:

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

 @param (?# find a param) \s* (?# whitespace) (\w+) (?# capture the variable) \s* (?# whitespace) (?: (?# start non capturing group) %(\w+): (?# capture the label) ([^%\n]+) (?# capture the text) )+ (?# repeat the non-capturing group) 

В этом примере я поместил код захвата меток / текста в группу, не связанную с захватом и повторением (1+ раз). Это позволяет нам сопоставить всю строку, но только последний набор меток / текстов захвачен (поскольку у нас есть только 3 группы: переменная, метка и текст).


Прямое решение:

Вместо этого вы можете просто совместить всю строку и затем анализировать строку метки / текста после факта:

 (?# match the whole string) @param (?# find a param) \s* (?# whitespace) (\w+) (?# capture the variable) \s* (?# whitespace) (.*) (?# capture the labels/texts) (?# parse the label/text string) % (?# the start of a label) (\w+) (?# capture label) : (?# end of label) ([^%]+) (?# capture text) 

Удивительное решение:

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

 (?: (?# start non-capturing group) @param (?# find a param) \s* (?# whitespace) (\w+) (?# capture the variable) \s* (?# whitespace) | (?# OR) \G (?# start back over from our last match) ) (?# end non-capturing group) %(\w+): (?# capture the label) ([^%\n]+) (?# capture the text) 

Это вращается вокруг магии PCRE \G , которая соответствует концу последнего матча. Поэтому мы запускаем группу, не @param захватом, которая будет содержать «префикс» определения @param . Это будет либо соответствовать, либо фиксировать переменную OR, начиная с конца нашего последнего совпадения. Затем мы сопоставляем / записываем 1 группу меток / текста. В следующий раз, когда он будет повторен, мы начнем с того места, где мы остановились, группа захвата переменных будет пустой (поскольку она не существует настолько далеко от строки, вам нужно будет использовать логику, чтобы узнать, в какой переменной вы находитесь) и захватить другую метку / текстовую группу (пока мы не нажмем на новую строку, так как я сказал, что текст не может быть % или \n ). Затем в следующей попытке поиска будет найдена новая переменная, определенная @param . Я думаю, что это будет ваш лучший вариант, это просто требует больше логики на вашем конце.

Если вы допустите, чтобы ваша средняя метка содержала : но вы не разрешаете ее на своем конце этикетке, я считаю, что ниже RegEx должен работать достаточно хорошо:

 @param\s+(.+?)\s+(.+:.+)\s+([^:]+:[^:]+)$ 

Однако это не сработает, если ваш шаблон охватывает несколько строк.

Кроме того, если вы пытаетесь разобрать PHPDoc или какой-либо его вариант, вы должны написать свой собственный парсер, используя RegEx.