Mirgorod
@Mirgorod

Regexp получить все символы заканчивая определённой последовательностью?

Здравствуйте, я пытаюсь создать свой шаблонизатор. Смарти и аналоги не подходят, так как мне нужен узконаправленный функционал, связанный с php, js, ajax. Стандартные шаблонизаторы для этого не подходят, а если и подходят, то придётся слишком долго пилить под необходимый функционал.


В данный момент создаю что-то на подобии цикла, вот как выглядит разметка:
{{crossLoopStart fromController-&gt;messages as message and increment|i every loop}}<br/>
wow, this is message number {{message-&gt;id}} and text is: {{message-&gt;text}}<br/>
{{crossLoopEmpty}}<br/>
oh no! You haven't any message!<br/>
{{crossLoopEnd}}



На данный момент я написал следующее regexp-выражение:
/\{\{crossLoopStart\s([a-zA-Z0-9&gt;-]+)\s(as\s([a-zA-Z&gt;-]+))?\s?and\s(([a-zA-Z0-9]+\|)?([a-zA-Z0-9]+)\s([a-z]+)\sloop)?\}\}/



Сейчас оно парсит только вот эту часть:
{{crossLoopStart fromController-&gt;messages as message and increment|i every loop}}



Но я не знаю как получить, всё остальное, что находится между
{{crossLoopStart fromController-&gt;messages as message and increment|i every loop}}


и
{{crossLoopEmpty}}

Т.е. данный участок кода:
wow, this is message number {{message-&gt;id}} and text is: {{message-&gt;text}}



Проблема в том, что если использовать (.+), то оно получит все символы. Это мне почти подходит, но я не знаю как сделать, чтобы оно взяло все символы до вот этой последовательности символов: {{crossLoopEmpty}} или до этой: {{crossLoopEnd}}


Заранее спасибо!
  • Вопрос задан
  • 5608 просмотров
Пригласить эксперта
Ответы на вопрос 6
@mr_idiot
Добавить (.+)(\{\{crossLoopEmpty\}\}|\{\{crossLoopEnd\}\})
не?
Ответ написан
$tpl = <<<end
{{crossLoopStart fromController->messages as message and increment|i every loop}}
wow, this is message number {{message->id}} and text is: {{message->text}}
{{crossLoopEmpty}}
oh no! You haven't any message!
{{crossLoopEnd}}
end;

preg_match('/\{\{crossLoopStart\s([a-zA-Z0-9>-]+)\s(?:as\s([a-zA-Z>-]+))?\s?and\s(?:([a-zA-Z0-9]+\|)?([a-zA-Z0-9]+)\s([a-z]+)\sloop)?\}\}'
        . '(?:[\r\n]?(.+?)[\r\n]?\{\{crossLoopEmpty\}\})?'
        . '(?:[\r\n]?(.+?)[\r\n]?\{\{crossLoopEnd\}\})/s', $tpl, $match);

var_dump($match);


Вывод:
array(8) {
[0]=>
string(224) "{{crossLoopStart fromController->messages as message and increment|i every loop}}
wow, this is message number {{message->id}} and text is: {{message->text}}
{{crossLoopEmpty}}
oh no! You haven't any message!
{{crossLoopEnd}}"
[1]=>
string(24) «fromController->messages»
[2]=>
string(7) «message»
[3]=>
string(10) «increment|»
[4]=>
string(1) «i»
[5]=>
string(5) «every»
[6]=>
string(74) «wow, this is message number {{message->id}} and text is: {{message->text}}»
[7]=>
string(31) «oh no! You haven't any message!»
}
Ответ написан
@max_rip
Ответ написан
Комментировать
knekrasov
@knekrasov
Вообще говоря, регулярные выражения для таких задач не предназначены. Разбирать контекстно-зависимые выражения бесконтекстной грамматикой — мысль все-таки порочная.
Я бы разбил выражение на лексемы и обработал вручную.
Ответ написан
Ваша регулрка должна выглдеть так:
/\{\{.*?\}\}/i
Дальше разбирать ручками.
Ответ написан
Комментировать
Подразумевает ли ваш шаблонизатор вложенные циклы?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы