Text Helper Utility Part 2: Separation of cased words

posted on 28th Feb 2007

Following yesterday's TextHelper.Coalesce post, I'd like to share another useful method for separating cased words i.e. PascalCase or camelCase.

There are a few reasons you might want to do this. It's common place today to use it in Javascript for dealing to CSS styles and the like. The inspiration behind this one was to be able to display the members of an enumeration in a meaningful way to the user e.g. using Enum.GetNames to bind possible values to a drop down list.

Consider the following enumeration:

public enum MyEnum
{
    Pending,
    Active,
    SaveForLater
}

When using Enum.GetNames(typeof(MyEnum)), the first two members are great, but the last member, SaveForLater, just doesn't look right when it comes to UI.

The following code would yield the string "Save For Later".

TextHelper.Separate(MyEnum.SaveForLater.ToString());

Enter TextHelper.Separate().

This method searches a given string prefixing a separator string when it finds an uppercase character. It also considers two uppercase characters in a row as an acronym and only appends the separator when the preceding character is lowercase.

To create the separate method, I compared a version done with regular expressions to the implementation below, which the non-regex version out-performed the regex by a factor of 11. So here's the code, again its simple, but extremely helpful when you need it.

public static class TextHelper
{
    public static string Separate(string casedWord, string separator)
    {
        var result = new StringBuilder();
        for (int i = 0, length = casedWord.Length; i < length; i++)
        {
            if (i > 0 && i < length - 1
                && char.IsUpper(casedWord[i])
                && !char.IsUpper(casedWord[i - 1]))
            {
                result.Append(separator);
            }
            result.Append(casedWord[i]);
        }
        return result.ToString();
    }

    public static string Separate(string casedWord)
    {
        return Separate(casedWord, " ");
    }

    public static string Hyphenate(string casedWord)
    {
        return Separate(casedWord, "-");
    }

    public static string ApplySpaces(string casedWord)
    {
        return Separate(casedWord, " ");
    }
}

You'll also notice the convenience Hyphenate method which is there for your, erm, convenience :)