Format capital letters at the start of a sentence I have a set of predefined templates for messages, where you can insert different arguments to make it more specific. 

In order for the messages to be looking good I needed a way to capitalize the first letters of each sentence because you might pass the argument fully lower-cased while in some messages that argument happen to be the start of the sentence which would require a capital letter at the start.

This is my extension method:

public static class Extensions
{
    private static readonly char[] _punctuationMarks = {'.', '!', '?'};

    public static string FormatCapitalLetters(this string source)
    {
        StringBuilder result = new StringBuilder();
        result.Append(source.First().ToUpper());
        for (int i = 1; i &lt; source.Length; i++)
        {
            result.Append(source[i]);
            if (IsPunctuationMark(source[i]))
            {
                int index = i + 1;
                if (index &gt;= source.Length || IsPunctuationMark(source[index]))
                {
                    continue;
                }
                if (source[index] == ' ')
                {
                    index++;
                }
                result.Append(' ');
                result.Append(source[index].ToUpper());
                i += index - i;
            }
        }
        return result.ToString();
    }

    private static string ToUpper(this char input) =&gt; input.ToString().ToUpper();

    private static bool IsPunctuationMark(char input) =&gt; _punctuationMarks.Any(
        punctuationMark =&gt; punctuationMark == input);
}


I'm looking for any comments on how to improve the current code or fix any flaws I'm unaware of, any alternative solutions are welcome as well.
Multispace bug

There is one flaw in this solution. It assumes a perfectly formatted sentence. This means that if there are multiple spaces between sentences the formatting won't work. For example it turns this "foo.  bar!    baz?" into "Foo.  bar!    baz?"

To fix this you either need another extension fixing all multiple spaces with a single one or make this one aware of this problem.


if (source[index] == ' ')
{
  index++;
}



This if should contain a continue but even with it, it won't work yet because the first if won't pass the second time. The logic is more complex and it would require a flag to skip "" spaces.



Trim


result.Append(source.First().ToUpper());



You assume that the first char is the first letter but you don't trim the source in case it isn't.



Naming


if (IsPunctuationMark(source[i]))
{
    int index = i + 1;
    if (index &gt;= source.Length || IsPunctuationMark(source[index]))
    {
        continue;
    }
    if (source[index] == ' ')
    {
        index++;
    }
    result.Append(' ');
    result.Append(source[index].ToUpper());
    i += index - i;
}



Here I find the index too general. It looks like it should be called e.g. firstLetterIndex.

Alternative? ;-)

You could use regex to clean-up the string.

public static string CapitalizeSentence(this string source)
{
    return 
        Regex
            .Replace(
                source.Trim(), 
                @"(^|(?&lt;Punctuation&gt;[.!?])\s*)(?&lt;FirstLetter&gt;[a-z])", 
                m =&gt; 
                    $"{(m.Groups["Punctuation"].Success ? m.Groups["Punctuation"].Value + " " : string.Empty)}" +
                    $"{m.Groups["FirstLetter"].Value.ToUpper()}");      
}