mash is correct, that would take code beyond just the preg_ functions:
<?php
$sourcestring="{happy} sometext sometext sometext {test {zebra} test} sometext sometext sometext {apple {red {crunchy}}} sometext {yay}";
echo "<pre>$sourcestring<hr>";
function assembleresult($match){
global $result;
$item=substr($match[0], 1, -1);
$result[]=$item;
return $item;
}
while(preg_match('/\{(?:(?>[^{}]+)|(?R))*\}/',$sourcestring)){
$sourcestring=preg_replace_callback('/\{(?:(?>[^{}]+)|(?R))*\}/','assembleresult',$sourcestring);
}
echo print_r($result,true);
?>
If the array order in your desired output is important then a modified solution based on array_map/array_slice etc. would be required instead of the while loop.