Is there an easy way to capitalize the first letter of a string and lower the rest of it? Is there a built in method or do I need to make my own?
-
4I don't know anything about your particular application, but I think a general warning is due: programmers shouldn't apply this method willy-nilly to real names. I think old John MacDonald would be upset this method mangling his name, not to mention e.e. cummings, bell hooks, danah boyd, 松本行弘, people with a "von" in the last name, people with the last name "O'Doyle", etc., etc., etc. Most names are not of the format "First Last" with that capitalization (and in capitalizable characters); I recommend reading http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/ – Nick Sep 14 '12 at 18:12
-
@Nick is absolutely right. You can't even assume that lower-case followed by upper-case is wrong - Irish names do things like "Ó hAirt". Assume that for any convention you can think of off the top of your head, there will be a culture/language that will surprise you. – James Moore Oct 26 '13 at 05:32
17 Answers
TextInfo.ToTitleCase()
capitalizes the first character in each token of a string.
If there is no need to maintain Acronym Uppercasing, then you should include ToLower()
.
string s = "JOHN DOE";
s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());
// Produces "John Doe"
If CurrentCulture is unavailable, use:
string s = "JOHN DOE";
s = new System.Globalization.CultureInfo("en-US", false).TextInfo.ToTitleCase(s.ToLower());
See the MSDN Link for a detailed description.

- 18,543
- 7
- 76
- 70

- 14,482
- 7
- 57
- 72
-
25One thing to note here is that it doesn't work if the string is all capitals. It thinks that all caps is an acronym. – Mike Roosa Sep 16 '08 at 14:55
-
9The thing I have seen with many of these is that you can't rely on them. It wouldn't work if the name is something like McCain or if you start hitting more foreign names. – Mike Wills Sep 16 '08 at 15:40
-
25
-
+1 I knew it had to already be in the FCL, and google brought me here =D – gideon Dec 09 '10 at 07:19
-
13Unlike Nathan's answer below, I get an error: "An object reference is required for the non-static field, method, or property......." unfortunately. – Dan W Sep 11 '12 at 22:52
-
In the author's defense, the incorrect code was added by an editor several years the original post, but I've corrected it to avoid any further confusion. – p.s.w.g Jun 30 '14 at 15:31
-
@Simon_Weaver Your comment helped me solve the `It thinks that all caps is an acronym.` caveat. Thanks! – hello Oct 19 '16 at 17:01
-
-
perhaps you should read the other comments before making a new one. That was answered above twice. – John Lord Nov 04 '18 at 08:38
CultureInfo.CurrentCulture.TextInfo.ToTitleCase("hello world");

- 20,233
- 5
- 52
- 56
-
Aww snap! Good answer. I always forget about the globalization stuff. – Michael Haren Sep 16 '08 at 14:32
-
Great solution! In VB.Net: `sItem = Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(sItem.ToLower) 'first char upper case` – Nasenbaer May 29 '13 at 09:18
-
You need to detect the culture of _each individual name_, not the current culture. This doesn't work for names. – James Moore Oct 26 '13 at 05:40
-
1Since this relies on the `CurrentCulture`, how can we be sure that there is no culture which handles this differently? – Rudey May 26 '14 at 21:09
String test = "HELLO HOW ARE YOU";
string s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(test);
The above code wont work .....
so put the below code by convert to lower then apply the function
String test = "HELLO HOW ARE YOU";
string s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(test.ToLower());

- 6,356
- 3
- 60
- 69

- 301
- 3
- 2
There are some cases that CultureInfo.CurrentCulture.TextInfo.ToTitleCase
cannot handle, for example : the apostrophe '
.
string input = CultureInfo.CurrentCulture.TextInfo.ToTitleCase("o'reilly, m'grego, d'angelo");
// input = O'reilly, M'grego, D'angelo
A regex can also be used \b[a-zA-Z]
to identify the starting character of a word after a word boundary \b
, then we need just to replace the match by its upper case equivalence thanks to the Regex.Replace(string input,string pattern,MatchEvaluator evaluator)
method :
string input = "o'reilly, m'grego, d'angelo";
input = Regex.Replace(input.ToLower(), @"\b[a-zA-Z]", m => m.Value.ToUpper());
// input = O'Reilly, M'Grego, D'Angelo
The regex can be tuned if needed, for instance, if we want to handle the MacDonald
and McFry
cases the regex becomes : (?<=\b(?:mc|mac)?)[a-zA-Z]
string input = "o'reilly, m'grego, d'angelo, macdonald's, mcfry";
input = Regex.Replace(input.ToLower(), @"(?<=\b(?:mc|mac)?)[a-zA-Z]", m => m.Value.ToUpper());
// input = O'Reilly, M'Grego, D'Angelo, MacDonald'S, McFry
If we need to handle more prefixes we only need to modify the group (?:mc|mac)
, for example to add french prefixes du, de
: (?:mc|mac|du|de)
.
Finally, we can realize that this regex will also match the case MacDonald'S
for the last 's
so we need to handle it in the regex with a negative look behind (?<!'s\b)
. At the end we have :
string input = "o'reilly, m'grego, d'angelo, macdonald's, mcfry";
input = Regex.Replace(input.ToLower(), @"(?<=\b(?:mc|mac)?)[a-zA-Z](?<!'s\b)", m => m.Value.ToUpper());
// input = O'Reilly, M'Grego, D'Angelo, MacDonald's, McFry

- 2,533
- 24
- 34
-
@polkduran I'm struggling to find a way to deal with roman numerals at the end of the name; I'd like to make them all uppercase: John Smith III. Would the negative look-behind interfere with this? – Matt Jul 03 '14 at 14:47
-
As it usually goes, I was finally able to answer my own question. I added an optional group to match roman numerals (which will get upper-cased). Here's the complete regex I'm using now: (?<=\b(?:mc|mac)?)[a-zA-Z](?<!'s\b)(?:ii|iii|iv|v|vi|vii|viii|ix)? – Matt Jul 03 '14 at 16:01
-
Your case is a special one, the regex in the answer treats each name (last name) as an isolated word in the input string (the test input string has several names) so it does not have the notion of 'end of the name'. If you treat the input string as a single name you can prefix the regex with a simple condition to deal with your case: `\b[ivxlcdm]+$|` so you have `\b[ivxlcdm]+$|(?<=\b(?:mc|mac)?)[a-zA-Z](?<!'s\b)`. It will make upercase all ending words of a name having a not strict roman numeral format (`ivxlcdm`). You may have however some undesired results, for instance 'Li' will become 'LI' – polkduran Jul 03 '14 at 16:04
-
Interesting. I think your addition is probably more correct regarding structure, but I agree... I think there will be some issues that you stated. In my solution above, I hard-coded the suffixes up to "ix" which will work in my case but I recognize may not be suitable for everyone. – Matt Jul 03 '14 at 16:11
-
Some people, when confronted with a problem, think “I know, I'll use regular expressions.” Now they have two problems. – David Clarke Jun 03 '15 at 23:43
-
@DavidClarke sometimes that's true, you can also implement your own algorithm, that's a relative simple regex. People say that when they don't know how to work with it. I have met people that says that for SQL for instance. – polkduran Jun 04 '15 at 17:33
-
I agree and I like regular expressions but it took a read of `Mastering Regular Expressions` before I felt comfortable that I had some idea what I was doing. Plus it's important to have an understanding of when to apply them to a problem because they can be brittle if used for a problem that has a high level of flux. – David Clarke Jun 05 '15 at 23:02
-
1@Si8, have you test it? `Regex.Replace("JOHN DOE".ToLower(), @"(?<=\b(?:mc|mac)?)[a-zA-Z](?<!'s\b)", m => m.Value.ToUpper())` – polkduran Nov 23 '16 at 15:52
-
Mc and Mac are common surname prefixes throughout the US, and there are others. TextInfo.ToTitleCase doesn't handle those cases and shouldn't be used for this purpose. Here's how I'm doing it:
public static string ToTitleCase(string str)
{
string result = str;
if (!string.IsNullOrEmpty(str))
{
var words = str.Split(' ');
for (int index = 0; index < words.Length; index++)
{
var s = words[index];
if (s.Length > 0)
{
words[index] = s[0].ToString().ToUpper() + s.Substring(1);
}
}
result = string.Join(" ", words);
}
return result;
}

- 48,427
- 16
- 81
- 117
The most direct option is going to be to use the ToTitleCase function that is available in .NET which should take care of the name most of the time. As edg pointed out there are some names that it will not work for, but these are fairly rare so unless you are targeting a culture where such names are common it is not necessary something that you have to worry too much about.
However if you are not working with a .NET langauge, then it depends on what the input looks like - if you have two separate fields for the first name and the last name then you can just capitalize the first letter lower the rest of it using substrings.
firstName = firstName.Substring(0, 1).ToUpper() + firstName.Substring(1).ToLower();
lastName = lastName.Substring(0, 1).ToUpper() + lastName.Substring(1).ToLower();
However, if you are provided multiple names as part of the same string then you need to know how you are getting the information and split it accordingly. So if you are getting a name like "John Doe" you an split the string based upon the space character. If it is in a format such as "Doe, John" you are going to need to split it based upon the comma. However, once you have it split apart you just apply the code shown previously.
I use my own method to get this fixed:
For example the phrase: "hello world. hello this is the stackoverflow world." will be "Hello World. Hello This Is The Stackoverflow World.". Regex \b (start of a word) \w (first charactor of the word) will do the trick.
/// <summary>
/// Makes each first letter of a word uppercase. The rest will be lowercase
/// </summary>
/// <param name="Phrase"></param>
/// <returns></returns>
public static string FormatWordsWithFirstCapital(string Phrase)
{
MatchCollection Matches = Regex.Matches(Phrase, "\\b\\w");
Phrase = Phrase.ToLower();
foreach (Match Match in Matches)
Phrase = Phrase.Remove(Match.Index, 1).Insert(Match.Index, Match.Value.ToUpper());
return Phrase;
}

- 31
- 1
CultureInfo.CurrentCulture.TextInfo.ToTitleCase ("my name");
returns ~ My Name
But the problem still exists with names like McFly as stated earlier.

- 51
- 1
-
3
-
@David C Try to replace space with null !! like string.replace(' ','') – Chintan Feb 10 '12 at 10:22
The suggestions to use ToTitleCase won't work for strings that are all upper case. So you are gonna have to call ToUpper on the first char and ToLower on the remaining characters.

- 2,926
- 1
- 23
- 27
-
6Why not call ToLower on the input string before calling ToTitleCase? – Andy Rose Sep 16 '08 at 15:48
This class does the trick. You can add new prefixes to the _prefixes static string array.
public static class StringExtensions
{
public static string ToProperCase( this string original )
{
if( String.IsNullOrEmpty( original ) )
return original;
string result = _properNameRx.Replace( original.ToLower( CultureInfo.CurrentCulture ), HandleWord );
return result;
}
public static string WordToProperCase( this string word )
{
if( String.IsNullOrEmpty( word ) )
return word;
if( word.Length > 1 )
return Char.ToUpper( word[0], CultureInfo.CurrentCulture ) + word.Substring( 1 );
return word.ToUpper( CultureInfo.CurrentCulture );
}
private static readonly Regex _properNameRx = new Regex( @"\b(\w+)\b" );
private static readonly string[] _prefixes = {
"mc"
};
private static string HandleWord( Match m )
{
string word = m.Groups[1].Value;
foreach( string prefix in _prefixes )
{
if( word.StartsWith( prefix, StringComparison.CurrentCultureIgnoreCase ) )
return prefix.WordToProperCase() + word.Substring( prefix.Length ).WordToProperCase();
}
return word.WordToProperCase();
}
}

- 573
- 6
- 12
If your using vS2k8, you can use an extension method to add it to the String class:
public static string FirstLetterToUpper(this String input)
{
return input = input.Substring(0, 1).ToUpper() +
input.Substring(1, input.Length - 1);
}

- 172,459
- 74
- 246
- 311
-
9`Char.ToUpper(input[0]) + input.Substring(1)` is more readable IMHO. – Hosam Aly Feb 11 '09 at 10:40
-
IMHO `input.FirstLetterToUpper()` is certainly more *readable* vs. `Char.ToUpper(input[0]) + input.Substring(1)`, but less *transparent* – Michael Jun 30 '14 at 15:39
I like this way:
using System.Globalization;
...
TextInfo myTi = new CultureInfo("en-Us",false).TextInfo;
string raw = "THIS IS ALL CAPS";
string firstCapOnly = myTi.ToTitleCase(raw.ToLower());
Lifted from this MSDN article.

- 430
- 4
- 16
Hope this helps you.
String fName = "firstname";
String lName = "lastname";
String capitalizedFName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(fName);
String capitalizedLName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(lName);

- 3,478
- 8
- 33
- 46
public static string ConvertToCaptilize(string input)
{
if (!string.IsNullOrEmpty(input))
{
string[] arrUserInput = input.Split(' ');
// Initialize a string builder object for the output
StringBuilder sbOutPut = new StringBuilder();
// Loop thru each character in the string array
foreach (string str in arrUserInput)
{
if (!string.IsNullOrEmpty(str))
{
var charArray = str.ToCharArray();
int k = 0;
foreach (var cr in charArray)
{
char c;
c = k == 0 ? char.ToUpper(cr) : char.ToLower(cr);
sbOutPut.Append(c);
k++;
}
}
sbOutPut.Append(" ");
}
return sbOutPut.ToString();
}
return string.Empty;
}

- 3,430
- 7
- 30
- 47
To get round some of the issues/problems that have ben highlighted I would suggest converting the string to lower case first and then call the ToTitleCase method. You could then use IndexOf(" Mc") or IndexOf(" O\'") to determine special cases that need more specific attention.
inputString = inputString.ToLower();
inputString = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(inputString);
int indexOfMc = inputString.IndexOf(" Mc");
if(indexOfMc > 0)
{
inputString.Substring(0, indexOfMc + 3) + inputString[indexOfMc + 3].ToString().ToUpper() + inputString.Substring(indexOfMc + 4);
}

- 5,890
- 6
- 40
- 62

- 16,770
- 7
- 43
- 49
Like edg indicated, you'll need a more complex algorithm to handle special names (this is probably why many places force everything to upper case).
Something like this untested c# should handle the simple case you requested:
public string SentenceCase(string input)
{
return input(0, 1).ToUpper + input.Substring(1).ToLower;
}

- 105,752
- 40
- 168
- 205
-
Forget this--use the globalization class http://stackoverflow.com/questions/72831/how-do-i-capitalize-first-letter-of-first-name-and-last-name-in-c#72871 – Michael Haren Sep 16 '08 at 14:33