Contact   •   Products   •   Search

Rick Strahl's Web Log

Wind, waves, code and everything in between...
ASP.NET • C# • HTML5 • JavaScript • AngularJs

Returning a proper case string in .Net


 

Ok, this is a simple one I ran across today after I was scavenging through my code trying to find a proper case converter I’d written a while back. Turns out there’s a much easier way using the TextInfo class:

 

public static string ProperCase(string Input)

{

      return System.Threading.Thread.CurrentThread.

             CurrentCulture.TextInfo.ToTitleCase(Input);

}

 

This has the additional advantage that it is culture aware since some countries don’t upper and lower the same way we do.

 

Who’d thunk this is available? FWIW, various Text formatting commands don’t live on the string class itself. I often use RegEx (for replacements especially), StringBuilder and now TextInfo for many string tasks. It’d sure would be nice if some of this was better cross referenced in the docs.

 

Apparently I’m not the only one who hasn’t found this one – I found at least 10 different snippets/articles that do this manually as well. This once again shows that knowing the BCL is what it’s all about – it’s probably in there if you can only find it <g>.

Make Donation


Feedback for this Post

 
# re: Returning a proper case string in .Net
by Scott Mitchell April 14, 2004 @ 3:39pm
It's too bad that they didn't make this a method of the String class, as it could just delegate the functionality to the TextInfo.ToTitleCase() method...
# re: Returning a proper case string in .Net
by Dale Rainsford June 02, 2004 @ 3:33am
Be careful when using this method. If you have the word all in uppercase it does not proper case, it leaves it in uppercase. The help mentions that implementation is subject to change.

# re: Returning a proper case string in .Net
by Craig December 08, 2004 @ 4:22pm
this solves the upper case issue

public static string ProperCase(string Input)

{

return System.Threading.Thread.CurrentThread.

CurrentCulture.TextInfo.ToTitleCase(Input.ToLower() );

}

# re: Returning a proper case string in .Net
by Stephen February 15, 2005 @ 7:59am
Thank you for your comments and solution for strings in all uppercase. That was driving me nuts and this was the only place I found a comment about it.
# re: Returning a proper case string in .Net
by Matt February 17, 2005 @ 4:44am
As per Stephen's comments above, thanks for the fix for the uppercase thing. Thought I was doing something stupid!
# Returning a proper case string in .Net
by kkc March 08, 2005 @ 9:45pm
Private Function ProperCase(ByVal strValue As String) As String
Try
ProperCase = StrConv(strValue, VbStrConv.ProperCase)
Catch ex As System.Exception
'Error hadler goes here
End Try
End Function

# Returning a proper case string in .Net
by kkc March 08, 2005 @ 9:45pm
Private Function ProperCase(ByVal strValue As String) As String
Try
ProperCase = StrConv(strValue, VbStrConv.ProperCase)
Catch ex As System.Exception
'Error hadler goes here
End Try
End Function

# re: Returning a proper case string in .Net
by Joe February 07, 2006 @ 3:34am
This works well for title case, but how about proper case? It doesn't properly capitalize O'Conner or McDonald (at least on my machine). If I am mistaken, please post your correction. I would appreciate it.
# re: Returning a proper case string in .Net
by Joe February 07, 2006 @ 3:39am
Sorry, here's a correwction to my previous post.

public static string ProperCase(string Input)
{
return System.Threading.Thread.CurrentThread.
CurrentCulture.TextInfo.ToTitleCase(Input);

}

works well for title case, but doesn't capitalize O'Conner or McDonald correctly.

I'm trying to avoid things like StrConv and rely on the Framework and not on VB6-style implementations.
# re: Returning a proper case string in .Net
by fwsteal September 12, 2006 @ 10:41am
i used it as such to list the contents of a directory and drop the file extension:

row[0] = ProperCase(info.Name);

public static string ProperCase(string Input)
{
char[] trimChars = { '.', 'a', 's', 'p', 'x' };
return System.Threading.Thread.CurrentThread.
CurrentCulture.TextInfo.ToTitleCase(Input.TrimEnd(trimChars));
}

# re: Returning a proper case string in .Net
by Stacey January 31, 2007 @ 8:21am
to handle " Mc " and " O' " :

        private string properCase(string Input) 
        {
            string output;
            output = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(Input.ToLower());
            output = output.Substring(0,2).CompareTo("Mc") == 0 ? "Mc" + properCase(output.Substring(2)) : output;
            output = output.Substring(0,2).CompareTo("O'") == 0 ? "O'" + properCase(output.Substring(2)) : output;
            return output;
        }
# re: Returning a proper case string in .Net
by sgt13echo October 02, 2007 @ 1:29pm
I am trying this and if I have a string like
"1234 WEST AVE. TAMPA BAY FL 33510"

The result is:
1234 West Ave. Tampa Bay Fl 33510"

Notice the "FL" now is "Fl'

I thought this would resolve it, but unfortunately it didn't, any help?

output = output.Substring(0, 2).CompareTo("FL") == 0 ? "FL" + properCase(output.Substring(2)) : output;
# re: Returning a proper case string in .Net
by dsmerchek October 09, 2007 @ 8:58am
shouldn't
output = output.Substring(0, 2).CompareTo("FL") == 0 ? "FL" + properCase(output.Substring(2)) : output;
be
output = output.Substring(0, 2).CompareTo("Fl") == 0 ? "FL" + properCase(output.Substring(2)) : output;
# Returning a proper case string in .Net
by DotNetKicks.com March 27, 2008 @ 2:26pm
You've been kicked (a good thing) - Trackback from DotNetKicks.com
# re: Returning a proper case string in .Net
by Patrick September 10, 2008 @ 5:50am
Stacey,

Awesome Solution! Recursive call to the method. Brilliant!!!

string output;
output = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(value.ToLower());
output = output.Substring(0, 2).CompareTo("Mc") == 0 ? "Mc" + ProperCase(output.Substring(2)) : output;
output = output.Substring(0, 2).CompareTo("O'") == 0 ? "O'" + ProperCase(output.Substring(2)) : output;
return output;

Thanks!!
# re: Returning a proper case string in .Net
by Brett November 05, 2008 @ 12:12pm
The only problem with Stacey's solution is that it will only work when MC or O' is the first word in the string.

In other words, "JOHN MCLOVIN" will be "John Mclovin"

To get "John McLovin", looks like we need to split the post ToTitleCase output and handle the words separately.
# re: Returning a proper case string in .Net
by Vikram Karumbaiah April 16, 2009 @ 6:53pm
This should solve the problem with names starting with Mc and O' as well as ending with 's

        /// <summary>
        /// Capitalize the first character of all words in the given string
        /// </summary>
        /// <param name="textToformat">Text to format as string</param>
        /// <returns>Returns the formatted text</returns>
        public static string InitCap(string textToformat)
        {
            // Got this code from http://www.windowsdevcenter.com/pub/a/oreilly/windows/news/csharp_0101.html
            string pattern = @"\w+|\W+";
            string result = "";
            Boolean capitalizeNext = true;
            foreach (Match m in Regex.Matches(textToformat, pattern))
            {
                // get the matched string
                string x = m.ToString().ToLower();

                // if the first char is lower case
                if (char.IsLower(x[0]) && capitalizeNext)
                {
                    // capitalize it
                    x = char.ToUpper(x[0]) + x.Substring(1, x.Length - 1);                    
                }

                // Check if the word starts with Mc
                if (x[0] == 'M' && x[1] == 'c' && !String.IsNullOrEmpty(x[2].ToString()))
                {
                    // Capitalize the letter after Mc
                    x = "Mc" + char.ToUpper(x[2]) + x.Substring(3, x.Length - 3);

                }

                if (capitalizeNext == false)
                    capitalizeNext = true;
                
                // if the apostrophe is at the end i.e. Andrew's
                // then do not capitalize the next letter
                if (x[0].ToString() == "'" && m.NextMatch().ToString().Length == 1)
                {
                    capitalizeNext = false;
                }

                // collect all text
                result += x;
            }
            return result;
        }
# re: Returning a proper case string in .Net
by Monty July 11, 2009 @ 2:39pm
Thanks Vikram, good stuff there! Besides the O'Whatevers and McWhatevers, what I like about yours over the StrConv() method is that a value like "52nd Street" does not become "52Nd Street". Thanks.

(Of course, is it any surprise a good algorithm for this would come from a place named "O'Reilly"? ;-)
# re: Returning a proper case string in .Net
by Mark Kamoski October 05, 2009 @ 8:57am
Vikram --

You may need to allow for names like...

D'AGOSTINO >>> D'Agostino

...etc.

Just a thought.

HTH.

Thank you.

-- Mark Kamoski
# re: Returning a proper case string in .Net
by Mark Kamoski October 05, 2009 @ 9:00am
Vikram --

I think you need to change from this...

if (x[0] == 'M' && x[1] == 'c' && !String.IsNullOrEmpty(x[2].ToString()))

...to this...

if (x[0] == 'M' && x.Length > 1 && x[1] == 'c' && !String.IsNullOrEmpty(x[2].ToString()))

...to allow for input that is a string containing a single-character that is the letter "M".

HTH.

Thank you.

-- Mark Kamoski
# re: Returning a proper case string in .Net
by Mark Kamoski October 05, 2009 @ 9:27am

All --

FWIW, I tweaked the code a bit to suit my needs, which may help others.

/// <summary>
/// This method will capitalize the first character of all words in the given string.
/// </summary>
/// <param name="textToformat">Text to format as string.</param>
/// <param name="addPeriodAfterSingleLetter">Add a period if desired.</param>
/// <returns>Returns the formatted text.</returns>
public static string GetNameProperCasing(string textToformat, bool addPeriodAfterSingleLetter)
{
    //This code is modified from the http://www.windowsdevcenter.com/pub/a/oreilly/windows/news/csharp_0101.html link and related posts.

    string pattern = @"\w+|\W+";
    string result = "";
    Boolean capitalizeNext = true;

    foreach (Match m in Regex.Matches(textToformat, pattern))
    {
        // get the matched string
        string x = m.ToString().ToLower();

        // if the first char is lower case
        if (char.IsLower(x[0]) && capitalizeNext)
        {
            // capitalize it
            x = char.ToUpper(x[0]) + x.Substring(1, x.Length - 1);
        }

        // Check if the word starts with Mc
        //if (x[0] == 'M' && x[1] == 'c' && !String.IsNullOrEmpty(x[2].ToString()))
        if (x[0] == 'M' && x.Length > 1 && x[1] == 'c' && !String.IsNullOrEmpty(x[2].ToString()))
        {
            // Capitalize the letter after Mc
            x = "Mc" + char.ToUpper(x[2]) + x.Substring(3, x.Length - 3);
        }

        if (capitalizeNext == false)
            capitalizeNext = true;

        // if the apostrophe is at the end i.e. Andrew's
        // then do not capitalize the next letter
        if (x[0].ToString() == "'" && m.NextMatch().ToString().Length == 1)
        {
            capitalizeNext = false;
        }

        // collect all text
        result += x;
    }

    if ((addPeriodAfterSingleLetter) && (result.Length == 1))
    {
        result = result + ".";
    }

    return result;
}


HTH.

Thank you.

-- Mark Kamoski
# re: Returning a proper case string in .Net
by Roy Cotton October 02, 2010 @ 10:26am
Wow I can't once again, one line of code will save me lots of work/time on my project, Keep it simple. Thanks rgc
# re: Returning a proper case string in .Net
by dingo99 October 20, 2010 @ 9:34pm
grrr! guys is it that hard?!! below fails on "mc";

if (x[0] == 'M' && x.Length > 1 && x[1] == 'c' && !String.IsNullOrEmpty(x[2].ToString()))

so clearly it needs to be x.Length > 2.

Same principal can be used for Mac, although there seems to be no definitive pattern, ie MacDonald, but not Macy or Mackie, MacPherson or Macpherson.
ok forget Mac, DiPi, de Jong, gotta love the english language!
 


West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2014