Counting the placeholders doesn't help - consider the following cases:
"{0} ... {1} ... {0}" - needs 2 values
"{1} {3}" - needs 4 values of which two are ignored
The second example isn't farfetched.
For example, you may have something like this in US English:
String.Format("{0} {1} {2} has a {3}", firstName, middleName, lastName, animal);
In some cultures, the middle name may not be used and you may have:
String.Format("{0} {2} ... {3}", firstName, middleName, lastName, animal);
If you want to do this, you need to look for the format specifiers {index[,length][:formatString]} with the maximum index, ignoring repeated braces (e.g. {{n}}). Repeated braces are used to insert braces as literals in the output string. I'll leave the coding as an exercise :) - but I don't think it can or should be done with Regex in the most general case (i.e. with length and/or formatString).
And even if you aren't using length or formatString today, a future developer may think it's an innocuous change to add one - it would be a shame for this to break your code.
I would try to mimic the code in StringBuilder.AppendFormat (which is called by String.Format) even though it's a bit ugly - use Lutz Reflector to get this code. Basically iterate through the string looking for format specifiers, and get the value of the index for each specifier.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…