Make first letter of a string upper case (with max

2019-01-01 15:13发布

问题:

I have a DetailsView with a TextBox and I want the input data be saved always with the FIRST LETTER IN CAPITAL.

Example:

\"red\" --> \"Red\"
\"red house\" --> \" Red house\"

How can I achieve this maximizing performance?


NOTE:
Based on the answers and the comments under the answers, many people think this is asking about capitalizing all words in the string. E.g. => Red House It isn\'t, but if that is what you seek, look for one of the answers that uses TitleInfo\'s ToTitleCase method. (NOTE: Those answers are incorrect for the question actually asked.)
See TextInfo.ToTitleCase doc for caveats (doesn\'t touch all-caps words - they are considered acronyms; may lowercase letters in middle of words that \"shouldn\'t\" be lowered, e.g. \"McDonald\" => \"Mcdonald\"; not guaranteed to handle all culture-specific subtleties re capitalization rules.)


NOTE:
The question is ambiguous as to whether letters after the first should be forced to lower case. The accepted answer assumes that only the first letter should be altered. If you want to force all letters in the string except the first to be lower case, look for an answer containing ToLower, and not containing ToTitleCase.

回答1:

EDIT: Updated to newer syntax (and more correct answer), also as an extension method.

public static class StringExtensions
{
    public static string FirstCharToUpper(this string input)
    {
        switch (input)
        {
            case null: throw new ArgumentNullException(nameof(input));
            case \"\": throw new ArgumentException($\"{nameof(input)} cannot be empty\", nameof(input));
            default: return input.First().ToString().ToUpper() + input.Substring(1);
        }
    }
}

OLD ANSWERS

public static string FirstCharToUpper(string input)
{
    if (String.IsNullOrEmpty(input))
        throw new ArgumentException(\"ARGH!\");
    return input.First().ToString().ToUpper() + String.Join(\"\", input.Skip(1));
}

EDIT: This version is shorter. For a faster solution take a look at Equiso\'s answer

public static string FirstCharToUpper(string input)
{
    if (String.IsNullOrEmpty(input))
        throw new ArgumentException(\"ARGH!\");
    return input.First().ToString().ToUpper() + input.Substring(1);
}

EDIT 2: Probably the fastest solution is Darren\'s (There\'s even a benchmark) although I would change it\'s string.IsNullOrEmpty(s) validation to throw an exception since the original requirement expects for a first letter to exist so it can be uppercased. Note that this code works for a generic string and not particularly on valid values from the Textbox.



回答2:

public string FirstLetterToUpper(string str)
{
    if (str == null)
        return null;

    if (str.Length > 1)
        return char.ToUpper(str[0]) + str.Substring(1);

    return str.ToUpper();
}

Old answer: This makes every first letter to upper case

public string ToTitleCase(string str)
{
    return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
}


回答3:

The right way is to use Culture:

Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(word.ToLower())

Note: This will capitalise each word within a string, e.g. \"red house\" --> \"Red House\". The solution will also lower-case capitalisation within words, e.g. \"old McDonald\" --> \"Old Mcdonald\".



回答4:

I took the fastest method from http://www.dotnetperls.com/uppercase-first-letter and converted to extension method:

    /// <summary>
    /// Returns the input string with the first character converted to uppercase, or mutates any nulls passed into string.Empty
    /// </summary>
    public static string FirstLetterToUpperCaseOrConvertNullToEmptyString(this string s)
    {
        if (string.IsNullOrEmpty(s))
            return string.Empty;

        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
    }

NOTE: The reason using ToCharArray is faster than the alternative char.ToUpper(s[0]) + s.Substring(1), is that only one string is allocated, whereas the Substring approach allocates a string for the substring, then a second string to compose the final result.


EDIT: Here is what this approach looks like, combined with the initial test from CarlosMuñoz accepted answer:

    /// <summary>
    /// Returns the input string with the first character converted to uppercase
    /// </summary>
    public static string FirstLetterToUpperCase(this string s)
    {
        if (string.IsNullOrEmpty(s))
            throw new ArgumentException(\"There is no first letter\");

        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
    }


回答5:

You can use \"ToTitleCase method\"

string s = new CultureInfo(\"en-US\").TextInfo.ToTitleCase(\"red house\");
//result : Red House

this extention method solve every titlecase problem.

easy to usage

string str = \"red house\";
str.ToTitleCase();
//result : Red house

string str = \"red house\";
str.ToTitleCase(TitleCase.All);
//result : Red House

the Extention method

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace Test
{
    public static class StringHelper
    {
        private static CultureInfo ci = new CultureInfo(\"en-US\");
        //Convert all first latter
        public static string ToTitleCase(this string str)
        {
            str = str.ToLower();
            var strArray = str.Split(\' \');
            if (strArray.Length > 1)
            {
                strArray[0] = ci.TextInfo.ToTitleCase(strArray[0]);
                return string.Join(\" \", strArray);
            }
            return ci.TextInfo.ToTitleCase(str);
        }
        public static string ToTitleCase(this string str, TitleCase tcase)
        {
            str = str.ToLower();
            switch (tcase)
            {
                case TitleCase.First:
                    var strArray = str.Split(\' \');
                    if (strArray.Length > 1)
                    {
                        strArray[0] = ci.TextInfo.ToTitleCase(strArray[0]);
                        return string.Join(\" \", strArray);
                    }
                    break;
                case TitleCase.All:
                    return ci.TextInfo.ToTitleCase(str);
                default:
                    break;
            }
            return ci.TextInfo.ToTitleCase(str);
        }
    }

    public enum TitleCase
    {
        First,
        All
    }
}


回答6:

For the first letter, with error checking:

public string CapitalizeFirstLetter(string s)
{
    if (String.IsNullOrEmpty(s))
        return s;
    if (s.Length == 1)
        return s.ToUpper();
    return s.Remove(1).ToUpper() + s.Substring(1);
}

And here\'s the same as a handy extension

public static string CapitalizeFirstLetter(this string s)
    {
    if (String.IsNullOrEmpty(s)) return s;
    if (s.Length == 1) return s.ToUpper();
    return s.Remove(1).ToUpper() + s.Substring(1);
    }


回答7:

public static string ToInvarianTitleCase(this string self)
{
    if (string.IsNullOrWhiteSpace(self))
    {
        return self;
    }

    return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(self);
}


回答8:

If performance/memory usage is an issue then, this one only creates one (1) StringBuilder and one (1) new String of the same size as the Original string.

public static string ToUpperFirst(this string str) {
  if( !string.IsNullOrEmpty( str ) ) {
    StringBuilder sb = new StringBuilder(str);
    sb[0] = char.ToUpper(sb[0]);

    return sb.ToString();

  } else return str;
}


回答9:

Try this:

static public string UpperCaseFirstCharacter(this string text) {
    return Regex.Replace(text, \"^[a-z]\", m => m.Value.ToUpper());
}


回答10:

Here\'s a way to do it as an extension method:

static public string UpperCaseFirstCharacter(this string text)
{
    if (!string.IsNullOrEmpty(text))
    {
        return string.Format(
            \"{0}{1}\",
            text.Substring(0, 1).ToUpper(),
            text.Substring(1));
    }

    return text;
}

Can then be called like:

//yields \"This is Brian\'s test.\":
\"this is Brian\'s test.\".UpperCaseFirstCharacter(); 

And here\'s some unit tests for it:

[Test]
public void UpperCaseFirstCharacter_ZeroLength_ReturnsOriginal()
{
    string orig = \"\";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual(orig, result);
}

[Test]
public void UpperCaseFirstCharacter_SingleCharacter_ReturnsCapital()
{
    string orig = \"c\";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual(\"C\", result);
}

[Test]
public void UpperCaseFirstCharacter_StandardInput_CapitalizeOnlyFirstLetter()
{
    string orig = \"this is Brian\'s test.\";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual(\"This is Brian\'s test.\", result);
}


回答11:

Since I happened to be working on this also, and was looking around for any ideas, this is the solution I came to. It uses LINQ, and will be able to capitalize the first letter of a string, even if the first occurrence isn\'t a letter. Here\'s the extension method I ended up making.

public static string CaptalizeFirstLetter(this string data)
{
    var chars = data.ToCharArray();

    // Find the Index of the first letter
    var charac = data.First(char.IsLetter);
    var i = data.IndexOf(charac);

    // capitalize that letter
    chars[i] = char.ToUpper(chars[i]);

    return new string(chars);
}

I\'m sure there\'s a way to optimize or clean this up a little bit.



回答12:

I found something here http://www.dotnetperls.com/uppercase-first-letter :

static string UppercaseFirst(string s)
{
// Check for empty string.
if (string.IsNullOrEmpty(s))
{
    return string.Empty;
}
// Return char and concat substring.
return char.ToUpper(s[0]) + s.Substring(1);
}

maybe this helps!!



回答13:

If you only care about first letter being capitalized and it does not matter the rest of the string you can just select the first character, make it upper case and concatenate it with the rest of the string without the original first character.

String word =\"red house\";
word = word[0].ToString().ToUpper() + word.Substring(1, word.length -1);
//result: word = \"Red house\"

We need to convert the first character ToString() because we are reading it as a Char array, and Char type does not have ToUpper() method.



回答14:

This will do it although it will also make sure that there are no errant capitals that are not at the beginning of the word.

public string(string s)
{
System.Globalization.CultureInfo c = new System.Globalization.CultureInfo(\"en-us\", false)
System.Globalization.TextInfo t = c.TextInfo;

return t.ToTitleCase(s);
}


回答15:

There seems to be a lot of complexity here when all you need is:

    /// <summary>
    /// Returns the input string with the first character converted to uppercase if a letter
    /// </summary>
    /// <remarks>Null input returns null</remarks>
    public static string FirstLetterToUpperCase(this string s)
    {
        if (string.IsNullOrWhiteSpace(s))
            return s;

        return char.ToUpper(s[0]) + s.Substring(1);
    }

Noteworthy points:

  1. Its an extension method.

  2. If the input is null, empty or whitespace the input is returned as is.

  3. String.IsNullOrWhiteSpace was introduced with .NET Framework 4. This won\'t work with older frameworks.



回答16:

Fastest method.

  private string Capitalize(string s){
        if (string.IsNullOrEmpty(s))
        {
            return string.Empty;
        }
        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
}

Tests show next results (string with 10000000 symbols as input): Test results



回答17:

string emp=\"TENDULKAR\";
string output;
output=emp.First().ToString().ToUpper() + String.Join(\"\", emp.Skip(1)).ToLower();


回答18:

I wanted to provide a \"MAXIMUM PERFORMANCE\" answer. In my mind, a \"MAXIMUM PERFORMANCE\" answer catches all scenarios and provides the answer to the question accounting for those scenarios. So, here is my answer. With these reasons:

  1. IsNullOrWhiteSpace accounts for strings that are just spaces or null/empty.
  2. .Trim() removes whitespace from the front and back of the string.
  3. .First() takes the first character of an ienumerable (or string).
  4. We should check to see if it is a letter that can/should be uppercase.
  5. We then add the rest of the string, only if the length indicates we should.
  6. By .Net best practice, we should provide a culture under System.Globalization.CultureInfo.
  7. Providing them as optional parameters makes this method totally reusable, without having to type the chosen culture every time.

    public static string capString(string instring, string culture = \"en-US\", bool useSystem = false)
    {
        string outstring;
        if (String.IsNullOrWhiteSpace(instring))
        {
            return \"\";
        }
        instring = instring.Trim();
        char thisletter = instring.First();
        if (!char.IsLetter(thisletter))
        {
            return instring;   
        }
        outstring = thisletter.ToString().ToUpper(new CultureInfo(culture, useSystem));
        if (instring.Length > 1)
        {
            outstring += instring.Substring(1);
        }
        return outstring;
    }
    


回答19:

This capitalizes this first letter and every letter following a space and lower cases any other letter.

public string CapitalizeFirstLetterAfterSpace(string input)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder(input);
    bool capitalizeNextLetter = true;
    for(int pos = 0; pos < sb.Length; pos++)
    {
        if(capitalizeNextLetter)
        {
            sb[pos]=System.Char.ToUpper(sb[pos]);
            capitalizeNextLetter = false;
        }
        else
        {
            sb[pos]=System.Char.ToLower(sb[pos]);
        }

        if(sb[pos]=\' \')
        {
            capitalizeNextLetter=true;
        }
    }
}


回答20:

Use the following code:

string  strtest =\"PRASHANT\";
strtest.First().ToString().ToUpper() + strtest.Remove(0, 1).ToLower();


回答21:

Seems like none of the solutions given here will deal with a white space before the string.

Just adding this as a thought:

public static string SetFirstCharUpper2(string aValue, bool aIgonreLeadingSpaces = true)
{
    if (string.IsNullOrWhiteSpace(aValue))
        return aValue;

    string trimmed = aIgonreLeadingSpaces 
           ? aValue.TrimStart() 
           : aValue;

    return char.ToUpper(trimmed[0]) + trimmed.Substring(1);
}   

It should handle this won\'t work on other answers (that sentence has a space in the beginning), and if you don\'t like the space trimming, just pass a false as second parameter (or change the default to false, and pass true if you want to deal with space)



回答22:

FluentSharp has the lowerCaseFirstLetter method which does this

https://github.com/o2platform/FluentSharp/blob/700dc35759db8e2164771a71f73a801aa9379074/FluentSharp.CoreLib/ExtensionMethods/System/String_ExtensionMethods.cs#L575



回答23:

It\'s fastest way:

public static unsafe void ToUpperFirst(this string str)
{
    if (str == null) return;
    fixed (char* ptr = str) 
        *ptr = char.ToUpper(*ptr);
}

Without changing original string:

public static unsafe string ToUpperFirst(this string str)
{
    if (str == null) return null;
    string ret = string.Copy(str);
    fixed (char* ptr = ret) 
        *ptr = char.ToUpper(*ptr);
    return ret;
}


回答24:

Easiest way to Capitalize firs letter is:

1- Using Sytem.Globalization;

  // Creates a TextInfo based on the \"en-US\" culture.
  TextInfo myTI = new CultureInfo(\"en-US\",false).

  myTI.ToTitleCase(textboxname.Text)

`



回答25:

the following function is correct for all ways:

static string UppercaseWords(string value)
{
    char[] array = value.ToCharArray();
    // Handle the first letter in the string.
    if (array.Length >= 1)
    {
        if (char.IsLower(array[0]))
        {
            array[0] = char.ToUpper(array[0]);
        }
    }
    // Scan through the letters, checking for spaces.
    // ... Uppercase the lowercase letters following spaces.
    for (int i = 1; i < array.Length; i++)
    {
        if (array[i - 1] == \' \')
        {
            if (char.IsLower(array[i]))
            {
                array[i] = char.ToUpper(array[i]);
            }
        }
    }
    return new string(array);
}

I found that here



回答26:

Expanding on Carlos\' question above, if you want to capitalize multiple sentences you may use this code:

    /// <summary>
    /// Capitalize first letter of every sentence. 
    /// </summary>
    /// <param name=\"inputSting\"></param>
    /// <returns></returns>
    public string CapitalizeSentences (string inputSting)
    {
        string result = string.Empty;
        if (!string.IsNullOrEmpty(inputSting))
        {
            string[] sentences = inputSting.Split(\'.\');

            foreach (string sentence in sentences)
            {
                result += string.Format (\"{0}{1}.\", sentence.First().ToString().ToUpper(), sentence.Substring(1)); 
            }
        }

        return result; 
    }


回答27:

Recently I had a similar requirement and remembered that the LINQ function Select() provides an index:

string input;
string output;

input = \"red house\";
output = String.Concat(input.Select((currentChar, index) => index == 0 ? Char.ToUpper(currentChar) : currentChar));
//output = \"Red house\"

Since I need that very often I made an extension method for the string type:

public static class StringExtensions
{
    public static string FirstLetterToUpper(this string input)
    {
        if (string.IsNullOrEmpty(input))
            return string.Empty;
        return String.Concat(input.Select((currentChar, index) => index == 0 ? Char.ToUpper(currentChar) : currentChar));
    }
}

Please note that only the first letter is converted to upper case - all remaining characters are not touched. If you need the other characters to be lower case you may also call Char.ToLower(currentChar) for index > 0 or call ToLower() on the whole string in the first place.

Regarding performance I compared the code with the solution from Darren. On my machine Darren\'s code is about 2 times faster which is no surprise since he\'s directly editing only the first letter within a char array. So I suggest you take Darren\'s code if you need the fastest solution available. If you want to integrate other string manipulations as well it may be convenient to have the expressive power of a lambda function touching the characters of the input string - you can easily extend this function - so I leave this solution here.



回答28:

I think the below method is the best solution

    class Program
{
    static string UppercaseWords(string value)
    {
        char[] array = value.ToCharArray();
        // Handle the first letter in the string.
        if (array.Length >= 1)
        {
            if (char.IsLower(array[0]))
            {
                array[0] = char.ToUpper(array[0]);
            }
        }
        // Scan through the letters, checking for spaces.
        // ... Uppercase the lowercase letters following spaces.
        for (int i = 1; i < array.Length; i++)
        {
            if (array[i - 1] == \' \')
            {
                if (char.IsLower(array[i]))
                {
                    array[i] = char.ToUpper(array[i]);
                }
            }
        }
        return new string(array);
    }

    static void Main()
    {
        // Uppercase words in these strings.
        const string value1 = \"something in the way\";
        const string value2 = \"dot net PERLS\";
        const string value3 = \"String_two;three\";
        const string value4 = \" sam\";
        // ... Compute the uppercase strings.
        Console.WriteLine(UppercaseWords(value1));
        Console.WriteLine(UppercaseWords(value2));
        Console.WriteLine(UppercaseWords(value3));
        Console.WriteLine(UppercaseWords(value4));
    }
}

Output

Something In The Way
Dot Net PERLS
String_two;three
 Sam

ref



回答29:

With this method you can upper the first char of every word.

Example \"HeLlo wOrld\" => \"Hello World\"

public static string FirstCharToUpper(string input)
{
    if (String.IsNullOrEmpty(input))
        throw new ArgumentException(\"Error\");
    return string.Join(\" \", input.Split(\' \').Select(d => d.First().ToString().ToUpper() +  d.ToLower().Substring(1)));
}


回答30:

send a string to this function. it will first check string is empty or null, if not string will be all lower chars. then return first char of string upper rest of them lower.

string FirstUpper(string s)
    {
        // Check for empty string.
        if (string.IsNullOrEmpty(s))
        {
            return string.Empty;
        }
        s = s.ToLower();
        // Return char and concat substring.
        return char.ToUpper(s[0]) + s.Substring(1);
    }