132

Is there a nice function to to turn something like

FirstName

to this:

First Name?

Old Man
  • 3,295
  • 5
  • 23
  • 22
  • 1
    This worked for me: `Regex.Replace(s, "([A-Z0-9]+)", " $1").Trim()`. And if you want to split on each capital letter, just remove the plus. – Mladen B. Mar 25 '19 at 17:17

6 Answers6

209

See: .NET - How can you split a "caps" delimited string into an array?

Especially:

Regex.Replace("ThisIsMyCapsDelimitedString", "(\\B[A-Z])", " $1")
Community
  • 1
  • 1
magma
  • 8,432
  • 1
  • 35
  • 33
  • 86
    Slightly better regex that handles acronyms correctly: `@"(\B[A-Z]+?(?=[A-Z][^A-Z])|\B[A-Z]+?(?=[^A-Z]))"` – Aviad P. Dec 24 '12 at 10:01
  • 11
    @AviadP. Fails for acronyms, e.g. `"HTMLGuide"` → `"H TML Guide"` – Matt Sep 14 '15 at 23:10
  • 7
    Modified slight to `Regex.Replace("ThisIsMy1stCapsDelimitedString", "(\\B[A-Z0-9])", " $1")` to split on numbers too. – garryp May 03 '17 at 16:07
  • 8
    This one actually works: (?<!^)([A-Z][a-z]|(?<=[a-z])[A-Z]) From: https://www.codeproject.com/Articles/108996/Splitting-Pascal-Camel-Case-with-RegEx-Enhancement – Vincent Jan 31 '19 at 19:04
  • "(\\B[A-Z](?!\\B[A-Z]))" <-- for acronyms works for me – jelde015 Mar 31 '23 at 20:15
163

Here's an extension method that I have used extensively for this kind of thing

public static string SplitCamelCase( this string str )
{
    return Regex.Replace( 
        Regex.Replace( 
            str, 
            @"(\P{Ll})(\P{Ll}\p{Ll})", 
            "$1 $2" 
        ), 
        @"(\p{Ll})(\P{Ll})", 
        "$1 $2" 
    );
}

It also handles strings like IBMMakeStuffAndSellIt, converting it to IBM Make Stuff And Sell It (IIRC).

Syntax explanation (credit):

{Ll} is Unicode Character Category "Letter lowercase" (as opposed to {Lu} "Letter uppercase"). P is a negative match, while p is a positive match, so \P{Ll} is literally "Not lowercase" and p{Ll} is "Lowercase".
So this regex splits on two patterns. 1: "Uppercase, Uppercase, Lowercase" (which would match the MMa in IBMMake and result in IBM Make), and 2. "Lowercase, Uppercase" (which would match on the eS in MakeStuff). That covers all camelcase breakpoints.
TIP: Replace space with hyphen and call ToLower to produce HTML5 data attribute names.

Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632
ZombieSheep
  • 29,603
  • 12
  • 67
  • 114
  • 2
    Thank you, works great! I just want to add that, I believe it would be much faster if Regex object was created statically using Compiled option instead of using static Regex.Replace method. – To Ka Aug 05 '15 at 22:58
  • 7
    Syntax explanation: `{Ll}` is Unicode Character Category "Letter lowercase" (as opposed to `{Lu}` "Letter uppercase"). 'P' is a negative match, while 'p' is a positive match, so `\P{Ll}` is literally "Not lowercase" and `p{Ll}` is "Lowercase". So this regex splits on two patterns. 1: "Uppercase, Uppercase, Lowercase" (which would match the 'MMa' in 'IBMMake' and result in 'IBM Make'), and 2. "Lowercase, Uppercase" (which would match on the 'eS' in 'MakeStuff'). That covers all camel case breakpoints. TIP: Replace space with hyphen and call `ToLower` to produce html5 data attribute names. – Triynko Sep 08 '15 at 03:07
  • 1
    I like this much more than the accepted answer as it doesn't creat "I B M Make Stuff And Sell It" – Jinjubei Dec 21 '16 at 15:05
  • Is there any problem with using `\p{Lu}` instead of `\P{Ll}`? – Andrew Jul 05 '17 at 17:16
  • Answering myself, I just did a few tests. Using `\p{Lu}` instead has issues with numbers. It would return "Has7Days" instead of "Has 7 Days". The only *issue* with this answer is that if there is a number that you don't want separated, like in "Se7en". Using `\P{Ll}` will separate that in three. As `\p{Lu}` as this number issue, it will just work fine. :D – Andrew Jul 05 '17 at 17:28
  • 1
    How would IBMMakeStuffAndSellIt actually be in camel case? "iBMMakeStuffAndSellIt"? – Andrew Jul 05 '17 at 17:45
  • 2
    @Andrew I think the usual convention is to lowercase all letters of leading acronym, so it would be "ibmMakeStuffAndSellIt". – amoss Jul 29 '19 at 18:38
  • @ToKa: compiled version here: https://stackoverflow.com/a/74831475/114029 – Leniel Maccaferri Dec 17 '22 at 02:51
12

Simplest Way:

var res = Regex.Replace("FirstName", "([A-Z])", " $1").Trim();
Karthik D V
  • 906
  • 1
  • 11
  • 19
7

You can use a regular expression:

Match    ([^^])([A-Z])
Replace  $1 $2

In code:

String output = System.Text.RegularExpressions.Regex.Replace(
                  input,
                  "([^^])([A-Z])",
                  "$1 $2"
                );
3
    /// <summary>
    /// Parse the input string by placing a space between character case changes in the string
    /// </summary>
    /// <param name="strInput">The string to parse</param>
    /// <returns>The altered string</returns>
    public static string ParseByCase(string strInput)
    {
        // The altered string (with spaces between the case changes)
        string strOutput = "";

        // The index of the current character in the input string
        int intCurrentCharPos = 0;

        // The index of the last character in the input string
        int intLastCharPos = strInput.Length - 1;

        // for every character in the input string
        for (intCurrentCharPos = 0; intCurrentCharPos <= intLastCharPos; intCurrentCharPos++)
        {
            // Get the current character from the input string
            char chrCurrentInputChar = strInput[intCurrentCharPos];

            // At first, set previous character to the current character in the input string
            char chrPreviousInputChar = chrCurrentInputChar;

            // If this is not the first character in the input string
            if (intCurrentCharPos > 0)
            {
                // Get the previous character from the input string
                chrPreviousInputChar = strInput[intCurrentCharPos - 1];

            } // end if

            // Put a space before each upper case character if the previous character is lower case
            if (char.IsUpper(chrCurrentInputChar) == true && char.IsLower(chrPreviousInputChar) == true)
            {   
                // Add a space to the output string
                strOutput += " ";

            } // end if

            // Add the character from the input string to the output string
            strOutput += chrCurrentInputChar;

        } // next

        // Return the altered string
        return strOutput;

    } // end method
1

Regex:

http://weblogs.asp.net/jgalloway/archive/2005/09/27/426087.aspx http://stackoverflow.com/questions/773303/splitting-camelcase

(probably the best - see the second answer) http://bytes.com/topic/c-sharp/answers/277768-regex-convert-camelcase-into-title-case

To convert from UpperCamelCase to Title Case, use this line : Regex.Replace("UpperCamelCase",@"(\B[A-Z])",@" $1");

To convert from both lowerCamelCase and UpperCamelCase to Title Case, use MatchEvaluator : public string toTitleCase(Match m) { char c=m.Captures[0].Value[0]; return ((c>='a')&&(c<='z'))?Char.ToUpper(c).ToString():" "+c; } and change a little your regex with this line : Regex.Replace("UpperCamelCase or lowerCamelCase",@"(\b[a-z]|\B[A-Z])",new MatchEvaluator(toTitleCase));

Ryan Bennett
  • 3,404
  • 19
  • 32