You're right, it doesn't work, and it's been submitted as a bug 🙂
There's a couple of work arounds for it. Last time, I used this one.
$result = preg_replace("/()()()()()()()()()\\[url\\](.*?)\[\\/url\\]/i", "\\\\101", "\[url\]blah\[/url\]");
echo $result;
And the result outputs: blah1
This works because you can only have 99 matches, so, the first 10 are empty, and \10 holds the one you want, and the 3rd number is treated as a literal. It sucks to do.
Then there's this method:
$result = preg_replace("/\\[url\\](.*?)\[\\/url\\]/i", "\\\\1_", "\[url\]blah\[/url\]");
$result = str_replace("_", "1", $result);
echo $result;
And once again the output is blah1. This method uses a non special character, then replaces it using the str_replace function with the number you want.
Doing this gets really messy. Ugh.
Hope that helps,
Matt