1

I'm trying to develop a function that can sort through a string that looks like this:

Donny went to the {park|store|{beach with friends|beach alone}} so he could get a breath of fresh air. 

What I intend to do is search the text recursively for {} patterns where there is no { or } inside the {}, so only the innermost sandwiched text is selected, where I will then run a php to array the contents and select one at random, repeating process until the whole string has been parsed, showing a complete sentence.

I just cannot wrap my head around regular expressions though.

Appreciate any help!

Alan Moore
  • 73,866
  • 12
  • 100
  • 156
Hudson Atwell
  • 192
  • 1
  • 4
  • 13
  • Gracious to everyone. Problem is slayed and staked. – Hudson Atwell Mar 15 '10 at 01:43
  • @adbox: what was the solution? if it was one of the answers below, you should mark it as accepted. if it wasn't one of the answers, write an answer yourself so people with the same problem can learn. – nickf Mar 19 '10 at 00:39
  • To accept an answer, click on the checkmark icon next to that answer. – Alan Moore Mar 19 '10 at 00:57

5 Answers5

2

Don't know about maths theory behind this ;-/ but in practice that's quite easy. Try

$text = "Donny went to the {park|store|{beach with friends|beach alone}} so he could get a breath of fresh air. ";

function rnd($matches) {
    $words = explode('|', $matches[1]);
    return $words[rand() % count($words)];
}

do {
    $text = preg_replace_callback('~{([^{}]+)}~', 'rnd', $text, -1, $count);
} while($count > 0);

echo $text;
user187291
  • 53,363
  • 19
  • 95
  • 127
1

Regexes are not capable of counting and therefore cannot find matching brackets reliably.

What you need is a grammar.

See this related question.

Community
  • 1
  • 1
Ben S
  • 68,394
  • 30
  • 171
  • 212
  • No, what he needs is a function which *uses* a regular expression. There is no need to solve the whole problem with a single regex. – Matteo Riva Mar 15 '10 at 01:06
  • Regex is overkill for such a simple operation. Save yourself some headaches later and write it "longhand" now. – Billy ONeal Mar 15 '10 at 01:15
  • No, he doesn't need a grammar and regexp is just the right tool for the job. See kemp's and mine answers. – user187291 Mar 15 '10 at 01:32
1
$str="Donny went to the {park|store|{beach {with friends}|beach alone}} so he could get a breath of fresh air. ";
$s = explode("}",$str);
foreach($s as $v){
 if(strpos($v,"{")!==FALSE){
  $t=explode("{",$v);
  print end($t)."\n";
 }
}

output

$ php test.php
with friends
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
0

You could do this with a lexer/parser. I don't know of any options in PHP (but since there are XML parsers in PHP, there are no doubt generic parsers). On the other hand, what you're asking to do is not too complicated. Using strings in PHP (substring, etc.) you could probably do this in a few recursive functions.

You will then finally have created a MadLibz generator in PHP with a simple grammar. Pretty cool.

Dan Rosenstark
  • 68,471
  • 58
  • 283
  • 421
0

Regular expressions don't deal well with recursive stuff, but PHP does:

$str = 'Donny went to the {park|store|{beach with friends|beach alone}} so he could get a breath of fresh air.';

echo parse_string($str), "\n";

function parse_string($string) {
    if ( preg_match('/\{([^{}]+)\}/', $string, $matches) ) {
        $inner_elements = explode('|', $matches[1]);
        $random_element = $inner_elements[array_rand($inner_elements)];
        $string = str_replace($matches[0], $random_element, $string);
        $string = parse_string($string);
    }
    return $string;
}
Matteo Riva
  • 24,728
  • 12
  • 72
  • 104