That's an interesting requirement... normally I don't spoon-feed code, but I don't think I've ever come across this type of situation so I thought I'd just have a go at it. Here's what I came up with:
$text = "I have a dog. My dog's name is tobby. My dog is cool.";
$text = preg_replace_callback(
'/dog/i',
create_function(
'$matches',
'$GLOBALS["num"] = (isset($GLOBALS["num"]) ? $GLOBALS["num"]+1 : 1); return "animal" . $GLOBALS["num"];'
),
$text
);
echo $num;
Only way I could think of doing it was to create a counter-variable in the global space... could cause a variable collision if you use $num in your code, in which case you'd have to pick a different name inside the create_function() code.
I'm sure sooner or later someone like Weedpacket will jump in with a more genius solution that doesn't have the limitations mine does... :p