Допустим, у меня есть:
$line = "{This is my {sentence|words} I wrote.}"
Вывод:
This is my sentence I wrote. This is my words I wrote.
Но регулярное выражение должно соответствовать глубоким и вложенным значениям и разделять эти значения, например:
$line = "{This is my {sentence|words} I wrote on a {sunny|cold} day.}";
Вывод:
This is my sentence I wrote on a sunny day. This is my sentence I wrote on a cold day. This is my words I wrote on a sunny day. This is my words I wrote on a cold day.
Мой первый, хотя и делал это над взрывом, как в коде ниже, но результат не подходит:
$res = explode("|", $line);
Советы? Спасибо.
EDIT: Что-то в этих строках:
$line = "{This is my {sentence|words} I wrote on a {sunny|cold} day.}"; $regex = "{[^{}]*}"; $match = []; preg_match($regex, $line, $match); var_dump($match);
Как уже было сказано, он может перейти к бесконечному, поэтому никакого предела, что-то в подходящем для цикла.
Проверь это. Я выполнил его, заменив ваши шаблоны на %s
и используя vsprintf
, а затем рекурсивный цикл через совпадения.
Я поместил много комментариев в код … понимание рекурсии – обычно довольно умственная работа.
Вот рабочий пример.
$line = "{This is my {sentence|statement} I {wrote|typed} on a {hot|cold} {day|night}.}"; $matches = getMatches($line); printWords([], $matches, $line); // function to find patterns in the line. Takes $line by reference to replace pattern matches with a vsprintf placeholder function getMatches(&$line) { // remove beginning and trailing brackets on the main sentence $line = trim($line, '{}'); // initialize variable that will hold the list of pattern matches $matches = null; // look for an opening curly brace and skip everything until the ending curly brace $pattern = '/\{[^}]+\}/'; // find all matches and put them in $matches preg_match_all($pattern, $line, $matches); // preg_match_all nests one level deeper than we need $matches = $matches[0]; // replace all matches with a %s placeholder $line = preg_replace($pattern, '%s', $line); // split each of the matches by vertical pipe foreach ($matches as $index => $match) { $matches[$index] = explode('|', trim($match, '{}')); } return $matches; } // recursive function. $args will be used as the second argument to vsprintf function printWords(array $args, array $matches, $line) { // get the first element in the array of $matches, remove it from the array $current = array_shift($matches); // keep track of the current $args index for this recursive iteration $currentArgIndex = count($args); // loop through each of the words in the current set of matches foreach ($current as $word) { // update $args and set the vsprintf argument at this iteration's position to the next word in the set of words $args[$currentArgIndex] = $word; if (!empty($matches)) { // repeat this process (recursively) until we are at the end of the list of matches printWords($args, $matches, $line); } else { // if this is the last match in the line, echo the sentence with all args from previous recursive iterations added echo vsprintf($line, $args) . '<br />'; } } }
Выходы:
Это мое предложение, которое я написал в жаркий день. Это мое предложение, которое я написал в жаркую ночь. Это мое предложение, которое я написал в холодный день. Это мое предложение, которое я написал в холодную ночь. Это мое предложение, которое я напечатал в жаркий день. Это мое предложение, которое я напечатал в жаркую ночь. Это мое предложение, которое я напечатал в холодный день. Это мое предложение, которое я напечатал в холодную ночь. Это мое заявление, которое я написал в жаркий день. Это мое заявление, которое я написал в жаркую ночь. Это мое заявление, которое я написал в холодный день. Это мое заявление, которое я написал в холодную ночь. Это мое заявление, которое я напечатал в жаркий день. Это мое заявление, которое я напечатал в жаркую ночь. Это мое заявление, которое я напечатал в холодный день. Это мое заявление, которое я напечатал в холодную ночь.