Как сделать, чтобы функция обрабатывалась рекурсивно?
Как сделать, чтобы функция обрабатывалась рекурсивно для шорткодов любой вложенности?
- [random]{Вариант1|Вариант2}[/random]
- {Вариант1|[random]Вариант2|Вариант2[/random]}
Сейчас возникает проблема, когда пытаюсь использовать [random][/random] внутри {}
function generateSpinText($template) { $processCurlyBraces = function($matches) use (&$processCurlyBraces, &$processRandomBraces) { $options = explode('|', $matches[1]); // Обработка вложенных скобок foreach ($options as &$option) { if (preg_match('/[random/', $option)) { $option = preg_replace_callback('/[random(d*)]([^[]*?)[/random]/s', $processRandomBraces, $option); } $option = preg_replace_callback('/{([^{}]+)}/', $processCurlyBraces, $option); } return $options[array_rand($options)]; }; $processRandomBraces = function($matches) use (&$processCurlyBraces, &$processRandomBraces) { $content = $matches[2]; $options = explode('|', $content); // Обработка вложенных скобок foreach ($options as &$option) { if (preg_match('/{/', $option)) { $option = preg_replace_callback('/{([^{}]+)}/', $processCurlyBraces, $option); } $option = preg_replace_callback('/[random(d*)]([^[]*?)[/random]/s', $processRandomBraces, $option); } $count = isset($matches[1]) && $matches[1] !== '' ? intval($matches[1]) : count($options); shuffle($options); $selectedOptions = array_slice($options, 0, $count); return implode('', $selectedOptions); }; // обработка {} while (preg_match('/{([^{}]+)}/', $template)) { $template = preg_replace_callback('/{([^{}]+)}/', $processCurlyBraces, $template); } // обработка [random][/random] while (preg_match('/[random(d*)]([^[]*?)[/random]/s', $template)) { $template = preg_replace_callback('/[random(d*)]([^[]*?)[/random]/s', $processRandomBraces, $template); } return $template; } |
function generateSpinText($template) { $processCurlyBraces = function($matches) use (&$processCurlyBraces, &$processRandomBraces) { $options = explode('|', $matches[1]); // Обработка вложенных скобок foreach ($options as &$option) { if (preg_match('/[random/', $option)) { $option = preg_replace_callback('/[random(d*)]([^[]*?)[/random]/s', $processRandomBraces, $option); } $option = preg_replace_callback('/{([^{}]+)}/', $processCurlyBraces, $option); } return $options[array_rand($options)]; }; $processRandomBraces = function($matches) use (&$processCurlyBraces, &$processRandomBraces) { $content = $matches[2]; $options = explode('|', $content); // Обработка вложенных скобок foreach ($options as &$option) { if (preg_match('/{/', $option)) { $option = preg_replace_callback('/{([^{}]+)}/', $processCurlyBraces, $option); } $option = preg_replace_callback('/[random(d*)]([^[]*?)[/random]/s', $processRandomBraces, $option); } $count = isset($matches[1]) && $matches[1] !== '' ? intval($matches[1]) : count($options); shuffle($options); $selectedOptions = array_slice($options, 0, $count); return implode('', $selectedOptions); }; // обработка {} while (preg_match('/{([^{}]+)}/', $template)) { $template = preg_replace_callback('/{([^{}]+)}/', $processCurlyBraces, $template); } // обработка [random][/random] while (preg_match('/[random(d*)]([^[]*?)[/random]/s', $template)) { $template = preg_replace_callback('/[random(d*)]([^[]*?)[/random]/s', $processRandomBraces, $template); } return $template; }
Дополнительно:
Вы бы лучше написали чего хотите добиться. Регулярки и реплэйсы и так рекурсивно работают
Ввод:
{Вариант1|[random]Вариант2|Вариант2[/random]}
Вывод (несколько итераций):
- [random]Вариант2
- Вариант2[/random]
- Вариант1
Ломается структура, когда [random][/random] внутри {}
Вывод (несколько итераций):
- Вариант1
- Вариант2Вариант2
У вас ищет рандом с цифрой
Для отладки регулярок
- {Привет|Здравствуй} вывдет либо Привет, либо здравствуй
- [random]Привет|Здравствуй[/random] выведет оба слова, но в разном порядке
И вот когда я вкладываю {Привет|random]Привет|Здравствуй[/random]}, то начинаются проблемы
$text = '{Привет|[Привет|Здравствуй|Хай|Здаров]|Не привет|[Один|Два]}'; preg_match_all('#[(.*)]#isU', $text, $matches); $words = []; foreach ($matches[1] as $val) { $str = explode('|', $val); $words[] = $str[array_rand($str)]; } $text = str_replace($matches[0], $words, $text); preg_match('#{(.*)}#isU', $text, $matches); $words1 = explode('|', $matches[1]); shuffle($words1); echo implode('|', $words1); |
$text = '{Привет|[Привет|Здравствуй|Хай|Здаров]|Не привет|[Один|Два]}'; preg_match_all('#[(.*)]#isU', $text, $matches); $words = []; foreach ($matches[1] as $val) { $str = explode('|', $val); $words[] = $str[array_rand($str)]; } $text = str_replace($matches[0], $words, $text); preg_match('#{(.*)}#isU', $text, $matches); $words1 = explode('|', $matches[1]); shuffle($words1); echo implode('|', $words1);
сократил рандом до квадратной скобки
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для того чтобы функция обрабатывалась рекурсивно, необходимо внутри самой функции вызывать её же. Рекурсия - это процесс, при котором функция вызывает саму себя, пока не будет достигнуто определенное условие выхода.
Пример использования рекурсии на языке PHP:
function recursiveFunction($number) { if ($number <= 0) { return; } echo $number; recursiveFunction($number - 1); } recursiveFunction(5);
В данном примере функция `recursiveFunction` будет вызывать саму себя с уменьшающимся аргументом `$number` до тех пор, пока `$number` не станет меньше или равным нулю. Когда условие `$number <= 0` будет выполнено, рекурсия завершится.
При использовании рекурсии важно учитывать условие выхода из рекурсии, чтобы избежать зацикливания и переполнения стека вызовов. Также необходимо следить за правильным порядком вызова функций в рекурсивном процессе.
Надеюсь, данное объяснение поможет вам понять, как сделать функцию обрабатывающейся рекурсивно. Если у вас возникнут дополнительные вопросы или потребуется помощь с конкретным примером, не стесняйтесь обращаться за помощью.