preg_replace with random selection

Discussion in 'PHP' started by goscript, Feb 4, 2008.

  1. #1
    Hi,
    Here is what I have:

    I have the above string. I need to select a random word from each of the { }

    Example result:

    Easiest way to do it?

    Thanks
     
    goscript, Feb 4, 2008 IP
  2. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #2
    
    $string = '{word1/word2/word3} {word4/word5/wor6/word7} {word8/word9}';
    $words = array();
    
    $sets = preg_split('~(\} )?[\{\}]~', $string, -1, PREG_SPLIT_NO_EMPTY);
    
    foreach ($sets AS $set)
    {
    	$tmp_words = explode('/', $set);
    	$words[] = $tmp_words[array_rand($tmp_words)];
    }
    
    print_r($words);
    
    PHP:
     
    nico_swd, Feb 4, 2008 IP
    goscript likes this.
  3. goscript

    goscript Prominent Member

    Messages:
    2,753
    Likes Received:
    306
    Best Answers:
    0
    Trophy Points:
    315
    #3
    Thanks nico, it works great.
    You saved me one more time :)

    One problem though.
    Between the } { it may be other characters.
    Ex:
    $string = '{word1/word2/word3} abc{word4/word5/wor6/word7}etc.{word8/word9}';
    PHP:
    I only need to choose a random word between { }, the rest should remain the same.

    So, I will output
    word2 abcword6etc.word8
    Code (markup):
    I do care about space chars, as I must output them too.

    Cheers mate
     
    goscript, Feb 4, 2008 IP
  4. joebert

    joebert Well-Known Member

    Messages:
    2,150
    Likes Received:
    88
    Best Answers:
    0
    Trophy Points:
    145
    #4
    <?php
    	$pat = '#\{(?:[^/]+/){%d}([^/}]+)(?:/[^}]+)?\} \{(?:[^/]+/){%d}([^/}]+)(?:/[^}]+)?\} \{(?:[^/]+/){%d}([^/}]+)(?:/[^}]+)?\}#';
    	$str = '{the cat/my dog/a super sexy cheetah} {drank/meowed loudly/went to the bathroom/chilled} {with me/by itself}';
    	$rpat = sprintf($pat, rand(0,2), rand(0,3), rand(0,1));
    	echo $rpat, '<br/>', preg_replace($rpat, "$1 $2 $3", $str)
    ?>
    PHP:
     
    joebert, Feb 4, 2008 IP
    goscript likes this.
  5. goscript

    goscript Prominent Member

    Messages:
    2,753
    Likes Received:
    306
    Best Answers:
    0
    Trophy Points:
    315
    #5
    Joebert only one problem. I may have more then 3 pairs of {}
    Your code works too, but not for more than 3 pairs.

    Thanks
     
    goscript, Feb 4, 2008 IP
  6. joebert

    joebert Well-Known Member

    Messages:
    2,150
    Likes Received:
    88
    Best Answers:
    0
    Trophy Points:
    145
    #6
    How many words/sections do you anticipate ?

    preg_replace can deal with a maximum of 99 back references.
     
    joebert, Feb 4, 2008 IP
  7. goscript

    goscript Prominent Member

    Messages:
    2,753
    Likes Received:
    306
    Best Answers:
    0
    Trophy Points:
    315
    #7
    It might be even more than 100 sections.
     
    goscript, Feb 4, 2008 IP
  8. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #8
    
    $string = '{word1/word2/word3} abc{word4/word5/wor6/word7}etc.{word8/word9}';
    $words = array();
    
    if (preg_match_all('~\{([^\}]+)\}~', $string, $matches))
    {
    	foreach ($matches[1] AS $set)
    	{
    		$tmp_words = explode('/', $set);
    		$words[] = $tmp_words[array_rand($tmp_words)];
    	}
    }
    
    print_r($words);
    
    
    PHP:
     
    nico_swd, Feb 4, 2008 IP
  9. kendo1979

    kendo1979 Peon

    Messages:
    208
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    0
    #9
    this is new information for me, thanks nico. a lot of your posts have improved my knowledge :)
     
    kendo1979, Feb 4, 2008 IP
  10. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #10
    He's called joebert. :p But you're welcome anyway, lol.
     
    nico_swd, Feb 4, 2008 IP
  11. joebert

    joebert Well-Known Member

    Messages:
    2,150
    Likes Received:
    88
    Best Answers:
    0
    Trophy Points:
    145
    #11
    preg_replace_callback might be a good fit with this task.

    <?php
    	$str = '{word1/word2/word3} abc{word4/word5/wor6/word7}etc.{word8/word9}';
    	
    	$str = preg_replace_callback(
    		'#\{[^}]+\}#',
    		create_function(
    			'$match',
    			'$match = explode(\'/\', trim($match[0], \'{}\')); return $match[rand(0,sizeof($match)-1)];'
    		),
    		$str
        );
        echo $str;
    ?>
    PHP:
     
    joebert, Feb 4, 2008 IP