tags:

views:

56

answers:

4

I'm currently attempting to present several enum's to the UI, albeit in a more friendly manner than a concatenated string.

public enum StoreMethod
{
   // Insert To Front
   InsertToFront,
   // Insert to End
   InsertToEnd,
   // Overwrite Existing
   OverwriteExisting,
   // Throw Exception If Exists
   ThrowExceptionIfExists
}

If I were to .ToString() on one of the values of the enum I'd get the string as written above. What I'd like is a regular expression to automatically insert a space before the any capital letters (with the exception of the first) or use a built-in BCL method (if one exists). The result of each would be as the comment indicates.

Is there a BCL method to be able to deconcatenate a string? or would a regular expression need to be used to achieve the results?

+1  A: 

I use the following method:

static Regex SpaceTrimmer = new Regex(@"\s+");
static readonly Regex CamelCaseSplitter = new Regex(@"_|(?<![A-Z])(?=[A-Z]+)|(?<=[A-Z])(?=[A-Z][^A-Z_])");
public static string SplitWords(this string name) {
    if (name == null) return null;

    return SpaceTrimmer.Replace(String.Join(" ",
        CamelCaseSplitter.Split(name)
                         .Select(s => s.Any(Char.IsLower) ? s.ToLower(CultureInfo.CurrentCulture) : s)
    ), " ").Trim();
}
SLaks
+3  A: 

You can place a description attribute above your enumeration items. Instead of parsing out the values, simply grab the description attribute and use it instead. Try this page -- Enum Description Attributes.

e.g.

public enum StoreMethod
{
   // Insert To Front
   [DescriptionAttribute("Insert To Front")]
   InsertToFront
}

This would be much cleaner and less error prone then attempting to parse the enumeration names. Plus, you can change the descriptions to anything you want without having to refactor your code in the future to account for a change in the enumeration name.

George
That can actually be shortened to [Description("Insert To Front")]. "*Attribute" can be omitted for all ComponentModel (or custom) annotations.
Peter J
@George. Have never seen that before. Thanks.
Jordan
I like this - however, having something more generic to handle all cases (including plain ol' strings) is more of the intent.
Michael
A: 
return Regex.Replace(input, @"(\p{Ll})(\p{Lu})", "$1 $2");

This will take anyplace where you have a lowercase letter followed by an uppercase letter, and insert a space between them. It should even work with non-English alphabets.

Joe White
+1  A: 

Using LINQ, you can call:

storeMethod.ToString().Aggregate("",
    (s, c) => s + (s != "" && char.IsUpper(c) ? " " + c : c.ToString()));

It will insert a space before each uppercase character excluding the first.

Jordan
I selected this answer because it eliminates any Regex's required to operate.
Michael
@Michael. Thanks and you're welcome.
Jordan