You can't just do a one-for-one swap with preg_replace_callback(). Have you checked out the manual page on the function? http://php.net/manual/en/function.preg-replace-callback.php
The second parameter needs to be a function name. It'll be passed the matches and you should return the string you want from there. Within that function is where you'd do the strlen() part.
function update($matches) {
return('s:' . strlen($matches[2]) . ":\"{$matches[2]}\";";
}
$unserialized = preg_replace_callback('!s:(\d+):"(.*?)";!',"update_function",$unserialized );
It's been a while since I've done this, so forgive any errors, but hopefully that gives you the idea. If you check out the manual page, you can also do an anonymous function, rather than defining update() or whatever you want to call it.
-John