Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Spintax Processor

I've been using the recurisve SpinTax processor as seen here, and it works just fine for smaller strings. However, it begins to run out of memory when the string goes beyond 20KB, and it's becoming a problem.

If I have a string like this:

{Hello|Howdy|Hola} to you, {Mr.|Mrs.|Ms.} {Smith|Williams|Austin}!

and I want to have random combinations of the words put together, and not use the technique as seen in the link above (recursing through the string until there are no more words in curly-braces), how should I do it?

I was thinking about something like this:

$array = explode(' ', $string);
foreach ($array as $k=>$v) {
        if ($v[0] == '{') {
                $n_array = explode('|', $v);
                $array[$k] = str_replace(array('{', '}'), '', $n_array[array_rand($n_array)]);
        }
}
echo implode(' ', $array);

But it falls apart when there are spaces in-between the options for the spintax. RegEx seems to be the solution here, but I have no idea how to implement it and have much more efficient performance.

Thanks!

like image 787
David Avatar asked Nov 20 '12 18:11

David


2 Answers

You could create a function that uses a callback within to determine which variant of the many potentials will be created and returned:

// Pass in the string you'd for which you'd like a random output
function random ($str) {
    // Returns random values found between { this | and }
    return preg_replace_callback("/{(.*?)}/", function ($match) {
        // Splits 'foo|bar' strings into an array
        $words = explode("|", $match[1]);
        // Grabs a random array entry and returns it
        return $words[array_rand($words)];
    // The input string, which you provide when calling this func
    }, $str);
}

random("{Hello|Howdy|Hola} to you, {Mr.|Mrs.|Ms.} {Smith|Williams|Austin}!");
random("{This|That} is so {awesome|crazy|stupid}!");
random("{StackOverflow|StackExchange} solves all of my {problems|issues}.");
like image 117
Sampson Avatar answered Nov 01 '22 05:11

Sampson


You can use preg_replace_callback() to specify a replacement function.

$str = "{Hello|Howdy|Hola} to you, {Mr.|Mrs.|Ms.} {Smith|Williams|Austin}!";

$replacement = function ($matches) {
    $array = explode("|", $matches[1]);
    return $array[array_rand($array)];
};

$str = preg_replace_callback("/\{([^}]+)\}/", $replacement, $str);
var_dump($str);
like image 42
Madara's Ghost Avatar answered Nov 01 '22 05:11

Madara's Ghost