2016-03-30 3 views
3

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

$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); 

Как уже говорилось, он может пойти на бесконечное, нет предела, то в для цикла необходимо.

+1

Я думаю, что вы можете создать функцию, которая _replaces_ первый матч [ '/ {[^ {}] *} /'] (HTTPS: //regex101.com/r/zV9sX0/1) и возвращает совпадение и его индекс ... Тогда, пока возврат не равен -1, вы продолжаете разрастание '' '... Конечно, вам понадобится массив нажмите каждый новый _sentence_ (состоящий из одного из вложенных значений, вставленных в индекс, возвращаемый функцией) –

+0

$ res = explode ("|", $ line, 2); –

+0

Я предполагаю, что количество вложенных уровней может быть любым, не так ли? Подобно '$ line =" {Это мое {предложение | слова}, которое я написал в {{very | not so} sunny | {freezing | rather} cold} day.} ";' –

ответ

3

Проверьте это. Я выполнил его, заменив ваши шаблоны на %s и используя vsprintf, а затем рекурсивно прокручивая спички.

Я положил много комментариев в код ... понимание рекурсии, как правило, довольно умственное задание.

Here is a working example.

$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 />'; 
     } 
    } 
} 

Выходы:

 
This is my sentence I wrote on a hot day. 
This is my sentence I wrote on a hot night. 
This is my sentence I wrote on a cold day. 
This is my sentence I wrote on a cold night. 
This is my sentence I typed on a hot day. 
This is my sentence I typed on a hot night. 
This is my sentence I typed on a cold day. 
This is my sentence I typed on a cold night. 
This is my statement I wrote on a hot day. 
This is my statement I wrote on a hot night. 
This is my statement I wrote on a cold day. 
This is my statement I wrote on a cold night. 
This is my statement I typed on a hot day. 
This is my statement I typed on a hot night. 
This is my statement I typed on a cold day. 
This is my statement I typed on a cold night. 
+0

Сумасшедший. Любите свое решение. –

+0

Хорошее решение, хотя это не работает для вложенных уровней. –

+0

@JamesBuck: Вы правы. И хотя ОП использовал слово «вложенный» в свой вопрос, я не видел примеров, которые предполагали, что он действительно нужен, и я не могу даже представить пример, когда вам понадобятся вложенные уровни для этого типа проблем. Поэтому я подумал, что он действительно не имел в виду «вложенные». – Travesty3