Try using preg_match_all()
$str = '../foo::bar{2}233{13}171{1}1{20}0.html';
$pattern = "/\{\d+\}/";
preg_match_all($pattern, $str, $matches);
$prevStart = 0;
foreach($matches[0] as $match)
{
$matchLen = strlen($match);
$matchPos = strpos($str, $match, $prevStart);
// Try to find the position of the next open curly brace
$openCurlyPos = strpos($str, '{', $matchPos + $matchLen);
// In case there is none found (.html comes up next), search for the . instead
if($openCurlyPos === false)
$openCurlyPos = strpos($str, '.', $matchPos + $matchLen);
$length = $openCurlyPos - ($matchPos + $matchLen);
$prevStart = $openCurlyPos;
echo $match.': '.substr($str, $matchPos + $matchLen, $length).'<br />';
}
/*
Result:
{2}: 233
{13}: 171
{1}: 1
{20}: 0
*/
I know this way might be pretty redundant, but I have no idea how to do this using regex. This also seems simpler to figure out for people.