Deep (infinite) separated words using regular expression

Let's say I have:

$line = "{This is my {sentence|words} I wrote.}" 

Output:

 This is my sentence I wrote. This is my words I wrote. 

But the regex must match deep and nested values ​​and separate these values, for example:

 $line = "{This is my {sentence|words} I wrote on a {sunny|cold} day.}"; 

Output:

 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. 

My first, although he did it over an explosion, as in the code below, but the result does not fit:

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

Advice? Thanks.

EDIT: Something on these lines:

 $line = "{This is my {sentence|words} I wrote on a {sunny|cold} day.}"; $regex = "{[^{}]*}"; $match = []; preg_match($regex, $line, $match); var_dump($match); 

As already mentioned, it can go to infinite, without restriction, something in a suitable cycle.

+3
source share
1 answer

Check this. I accomplished this by replacing your templates with %s and using vsprintf and then a recursive loop through matches.

I put a lot of comments into the code ... understanding recursion is usually pretty mental work.

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

Outputs:

  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.
+3
source

All Articles