Split a PascalCase string into separate words

See this question: Is there a elegant way to parse a word and add spaces before capital letters? Its accepted answer covers what you want, including numbers and several uppercase letters in a row. While this sample has words starting in uppercase, it it equally valid when the first word is in lowercase.

string[] tests = {
   "AutomaticTrackingSystem",
   "XMLEditor",
   "AnXMLAndXSLT2.0Tool",
};


Regex r = new Regex(
    @"(?<=[A-Z])(?=[A-Z][a-z])|(?<=[^A-Z])(?=[A-Z])|(?<=[A-Za-z])(?=[^A-Za-z])"
  );

foreach (string s in tests)
  r.Replace(s, " ");

The above will output:

[Automatic][Tracking][System]
[XML][Editor]
[An][XML][And][XSLT][2.0][Tool]

How about:

static IEnumerable<string> SplitPascalCase(this string text)
{
    var sb = new StringBuilder();
    using (var reader = new StringReader(text))
    {
        while (reader.Peek() != -1)
        {
            char c = (char)reader.Read();
            if (char.IsUpper(c) && sb.Length > 0)
            {
                yield return sb.ToString();
                sb.Length = 0;
            }

            sb.Append(c);
        }
    }

    if (sb.Length > 0)
        yield return sb.ToString();
}

Answered in a different question:

void Main()
{
    "aCamelCaseWord".ToFriendlyCase().Dump();
}

public static class Extensions
{
    public static string ToFriendlyCase(this string PascalString)
    {
        return Regex.Replace(PascalString, "(?!^)([A-Z])", " $1");
    }
}

Outputs a Camel Case Word (.Dump() just prints to the console).


Just to provide an alternative to the RegEx and looping solutions all ready provided here is an answer using LINQ which also handles camel case and acronyms:

    string[] testCollection = new string[] { "AutomaticTrackingSystem", "XSLT", "aCamelCaseWord" };
    foreach (string test in testCollection)
    {
        // if it is not the first character and it is uppercase
        //  and the previous character is not uppercase then insert a space
        var result = test.SelectMany((c, i) => i != 0 && char.IsUpper(c) && !char.IsUpper(test[i - 1]) ? new char[] { ' ', c } : new char[] { c });
        Console.WriteLine(new String(result.ToArray()));
    }

The output from this is:

Automatic Tracking System  
XSLT  
a Camel Case Word 

Tags:

.Net

Regex