cassiusA Posted September 20, 2010 Share Posted September 20, 2010 Hi, I'm trying to learn some php and have hit a stumbling block on something I'm working on. I have a string that contains the following value: {Cats|Dogs|Mice} and a {Monkey|Chimp} I would like to randomly select 1 item from each group of animals. So results would look like "Cats and a Monkey" or "Mice and a Chimp" for example. This is the code I currently have written to get started, but it's not quite doing what I expected. <?php $content_str = "{Cats|Dogs|Mice} and a {Monkey|Chimp}"; preg_match("|{(.+)}|si", $content_str, $inside); $contents = preg_split('/\|/', $inside[1], -1, PREG_SPLIT_OFFSET_CAPTURE); $pieces = explode("|", $inside[1]); $result = count($contents); $word = $pieces[rand(0, $result-1)]; echo $inside[1]; ?> Obviously my code is incomplete for the examples above. At this point, I was kind of expecting to see something like: "Cats|Dogs|Mice and a Monkey|Chimp" or "Cats|Dogs|Mice and a {Monkey|Chimp}" What I'm actually getting is "Cats|Dogs|Mice} and a {Monkey|Chimp" So my code is finding and removing the correct characters ( '{' and '}' ), however it's only removing the first and the last. Ideally, I'd like for it to remove every set and put each sequence of words, cats|dogs|mice for example, into an array so I can call them directly. Any ideas about what I need to do, or of a better way going about doing this? Cheers Quote Link to comment https://forums.phpfreaks.com/topic/213905-preg_match-matching-only-first-and-last-result/ Share on other sites More sharing options...
.josh Posted September 20, 2010 Share Posted September 20, 2010 it's because you are using a greedy quantifier (.+) so it matches all the way to the last instance of } instead of (.+) make it lazy by doing (.+?) or better yet, use a negative character class: ([^}]+) couple other things: preg_match() only matches first instance, I'm not 100% sure what you're trying to accomplish but you will probably want to change that to preg_match_all(). Also, after the preg_match you are using preg_split to further break down the values...but since you are just using | as a delim (a static delimiter) you should be better off just using explode for that bit. Quote Link to comment https://forums.phpfreaks.com/topic/213905-preg_match-matching-only-first-and-last-result/#findComment-1113314 Share on other sites More sharing options...
cassiusA Posted September 20, 2010 Author Share Posted September 20, 2010 Thank you for the fantastic (and fast!) feedback, Crayon Violent. Given what you've suggested, I guessing it should look something more like this then. Untested preg_match_all('|({[^}]+})|', $content_str, $inside, PREG_PATTERN_ORDER); As for using explode, I will definitely use that moving forward. I wasn't even aware of it's existence. Quote Link to comment https://forums.phpfreaks.com/topic/213905-preg_match-matching-only-first-and-last-result/#findComment-1113319 Share on other sites More sharing options...
fortnox007 Posted September 20, 2010 Share Posted September 20, 2010 why don't you just put the cats mice and monkeys in an array and than choose a random? seems more flexible Quote Link to comment https://forums.phpfreaks.com/topic/213905-preg_match-matching-only-first-and-last-result/#findComment-1113353 Share on other sites More sharing options...
.josh Posted September 20, 2010 Share Posted September 20, 2010 my guess is it's a template system of sorts, where people can define content and sub-content. Quote Link to comment https://forums.phpfreaks.com/topic/213905-preg_match-matching-only-first-and-last-result/#findComment-1113355 Share on other sites More sharing options...
salathe Posted September 21, 2010 Share Posted September 21, 2010 Here's a brief example which uses preg_replace_callback and a bespoke callback function to replace the tags with one of the words at random. function choose_word($match) { $options = explode('|', $match[1]); return $options[array_rand($options)];}$subject = "{Cats|Dogs|Mice} and a {Monkey|Chimp}";$phrase = preg_replace_callback('/{([^{}]+)}/', 'choose_word', $subject);echo $phrase; Quote Link to comment https://forums.phpfreaks.com/topic/213905-preg_match-matching-only-first-and-last-result/#findComment-1113629 Share on other sites More sharing options...
cassiusA Posted September 21, 2010 Author Share Posted September 21, 2010 That looks like nice and clean code, salathe. Thanks for the follow-up. I did manage to get it working mostly, but your code is much shorter than mine.. Quote Link to comment https://forums.phpfreaks.com/topic/213905-preg_match-matching-only-first-and-last-result/#findComment-1113787 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.