关于c#:使字符串大写的第一个字母(具有最大性能)

Make first letter of a string upper case (with maximum performance)

我有一个DetailsView和一个TextBox我希望输入的数据总是用大写的第一个字母保存。

例子:

1
2
"red" -->"Red"
"red house" -->" Red house"

我如何才能实现这一最大化的性能?

注:根据答案和答案下面的注释,许多人认为这是在问字符串中所有单词的大写。例如,=> Red House不是,但如果这是你所寻求的,寻找使用TextInfoToTitleCase方法的答案之一。(注:这些答案对实际提问不正确。)有关注意事项,请参阅textinfo.toitlecase doc(不要触摸所有大写字母-它们被视为首字母缩略词;可能在单词中间出现小写字母"不应"被降低,例如"McDonald"=>"McDonald";不保证能够处理所有特定于文化的细微差别重新大写规则。)

注:关于第一个字母后面的字母是否应该强制小写,这个问题是模棱两可的。接受的回答假定只应更改第一个字母。如果要强制字符串中除第一个字母为小写以外的所有字母,请查找包含ToLower而不包含toitlecase的答案。


编辑:更新为新的语法(和更正确的答案),也作为扩展方法。

1
2
3
4
5
6
7
8
9
10
11
12
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);
        }
    }
}

旧答案

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

编辑:此版本较短。要获得更快的解决方案,请看Equiso的答案。

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

编辑2:也许最快的解决方案是Darren的(甚至有一个基准),尽管我会改变它的string.IsNullOrEmpty(s)验证来抛出一个异常,因为最初的需求期望第一个字母存在,所以它可以是大写的。请注意,此代码适用于一般字符串,而不特别适用于来自Textbox的有效值。


1
2
3
4
5
6
7
8
9
10
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();
}

老回答:这使得每个第一个字母都大写

1
2
3
4
public string ToTitleCase(string str)
{
    return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
}


正确的方法是使用文化:

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

注意:这将在一个字符串中大写每个单词,例如"Red House"-->"Red House"。该解决方案还将降低大写字母,例如"Old McDonald"-->"Old McDonald"。


我从http://www.dotnetperls.com/uppercase-first-letter中选择了最快的方法,并转换为扩展方法:

1
2
3
4
5
6
7
8
9
10
11
12
    /// <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);
    }

注:使用ToCharArray比替代的char.ToUpper(s[0]) + s.Substring(1)更快的原因是只分配了一个字符串,而Substring方法为子字符串分配了一个字符串,然后再分配第二个字符串来组成最终结果。

编辑:这是这个方法看起来的样子,加上卡洛斯穆的初始测试?oz接受的答案:

1
2
3
4
5
6
7
8
9
10
11
12
    /// <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);
    }


您可以使用"toitlecase方法"

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

这种扩展方法解决了每一个题库问题。

易用

1
2
3
4
5
6
7
string str ="red house";
str.ToTitleCase();
//result : Red house

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

延伸法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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
    }
}


对于第一个字母,进行错误检查:

1
2
3
4
5
6
7
8
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);
}

这里有一个方便的扩展名

1
2
3
4
5
6
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);
    }


1
2
3
4
5
6
7
8
9
public static string ToInvarianTitleCase(this string self)
{
    if (string.IsNullOrWhiteSpace(self))
    {
        return self;
    }

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

如果性能/内存使用是一个问题,那么这个问题只创建一(1)个StringBuilder和一(1)个与原始字符串大小相同的新字符串。

1
2
3
4
5
6
7
8
9
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;
}


试试这个:

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


以下是作为扩展方法执行此操作的方法:

1
2
3
4
5
6
7
8
9
10
11
12
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;
}

可以这样称呼:

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

下面是一些单元测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[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);
}


因为我碰巧也在研究这个,并且四处寻找任何想法,这就是我找到的解决方案。它使用LINQ,并且能够将字符串的第一个字母大写,即使第一个字母不是字母。这是我最后制作的扩展方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
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);
}

我相信有一种方法可以优化或清理这一点。


我在这里找到了一些东西http://www.dotnetperls.com/uppercase-first-letter:

1
2
3
4
5
6
7
8
9
10
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);
}

也许这有帮助!!


如果只关心首字母大写,而不关心字符串的其余部分,您可以只选择第一个字符,将其设为大写,然后将其与字符串的其余部分连接起来,而不使用原始首字符。

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

我们需要将第一个字符转换为string(),因为我们将其作为char数组读取,char类型没有toupper()方法。


最快的方法。

1
2
3
4
5
6
7
8
9
  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);
}

测试显示下一个结果(输入10000000个符号的字符串):试验结果


这将做到这一点,尽管它也将确保没有不在单词开头的错误的大写字母。

1
2
3
4
5
6
7
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);
}


当你需要的只是:

1
2
3
4
5
6
7
8
9
10
11
    /// <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);
    }

注意事项:

  • 它是一种扩展方法。

  • 如果输入为空、空或空白,则按原样返回输入。

  • String.IsNullorWhitespace是随.NET Framework 4引入的。这不适用于旧框架。


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


    我想提供一个"最高性能"的答案。在我看来,一个"最高性能"的答案可以捕捉所有场景,并提供对这些场景进行解释的问题的答案。所以,这是我的答案。基于这些原因:

  • IsNullOrWhiteSpace只包含空格或空/空字符串。
  • .trim()删除字符串前后的空白。
  • .first()接受IEnumerable(或字符串)的第一个字符。
  • 我们应该检查一下这是不是一个大写字母。
  • 然后我们添加字符串的其余部分,前提是长度指示我们应该添加。
  • 根据.NET最佳实践,我们应该提供System.Globalization.CultureInfo下的文化。
  • 将它们作为可选参数提供会使此方法完全可重用,而不必每次都键入所选的区域性。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    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;
    }

  • 我认为下面的方法是最好的解决办法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
        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

    裁判


    最近我有一个类似的要求,并记住linq函数select()提供了一个索引:

    1
    2
    3
    4
    5
    6
    string input;
    string output;

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

    因为我经常需要这样做,所以我为字符串类型创建了一个扩展方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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));
        }
    }

    请注意,只有第一个字母被转换为大写-所有剩余的字符都不会被触摸。如果需要其他字符的大小写为小写,还可以首先调用char.to lower(currentchar)for index>0或调用整个字符串的tolower()。

    关于性能,我将代码与Darren的解决方案进行了比较。在我的机器上,darren的代码快了2倍,这并不奇怪,因为他只直接编辑char数组中的第一个字母。因此,如果您需要最快的解决方案,我建议您使用Darren的代码。如果您还想集成其他字符串操作,那么让lambda函数的表达能力接触到输入字符串的字符可能很方便—您可以轻松地扩展这个函数—所以我把这个解决方案留在这里。


    这将第一个字母和后面的每一个字母都大写,并且小写任何其他字母。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    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;
            }
        }
    }


    展开上面卡洛斯的问题,如果你想将多个句子大写,你可以使用以下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
        /// <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;
        }

    以下功能适用于所有方式:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    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);
    }

    我在这里找到的


    似乎这里给出的所有解决方案都不会处理字符串前面的空白。

    只是在想一想:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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);
    }

    它应该处理this won't work on other answers(那句话开头有空格),如果你不喜欢空格修剪,只需要把false作为第二个参数传递(或者把默认值改为false,如果你想处理空格,就传递true)


    使用以下代码:

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


    这是最快的方法:

    1
    2
    3
    4
    5
    6
    public static unsafe void ToUpperFirst(this string str)
    {
        if (str == null) return;
        fixed (char* ptr = str)
            *ptr = char.ToUpper(*ptr);
    }

    不更改原始字符串:

    1
    2
    3
    4
    5
    6
    7
    8
    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;
    }


    Fluentsharp有一个lowerCaseFirstLetter方法,它可以做到这一点。

    https://github.com/o2platform/fluentsharp/blob/700dc35759db8e2164771a71f73a801aa9379074/fluentsharp.corelib/extensionmethods/system/string_extensionmethods.cs l575


    首字母大写的最简单方法是:

    1-使用系统全球化;

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

      myTI.ToTitleCase(textboxname.Text)

    `


    用这种方法,你可以把每个单词的第一个字符加上。

    例子"Hello World"=>"你好,世界"

    1
    2
    3
    4
    5
    6
    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)));
    }

    向此函数发送字符串。它将首先检查字符串是否为空,如果不是,则字符串将全部是较低的字符。然后返回字符串的第一个字符,其上半部分位于下半部分。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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);
        }


    正如Bobbeechey在回答这个问题时所建议的,下面的代码可以解决这个问题:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    private void txt_fname_TextChanged(object sender, EventArgs e)
    {
        char[] c = txt_fname.Text.ToCharArray();
        int j;
        for (j = 0; j < txt_fname.Text.Length; j++)
        {
            if (j==0) c[j]=c[j].ToString().ToUpper()[0];
            else c[j] = c[j].ToString().ToLower()[0];
        }
        txt_fname.Text = new string(c);
        txt_fname.Select(txt_fname.Text.Length, 1);
    }


    我用这个来改名字。它基本上是在将一个字符改变为大写的概念上工作的,如果它遵循一个特定的模式,在这种情况下,我已经为空间,破折号"mc"。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    private String CorrectName(String name)
            {
                List<String> StringsToCapitalizeAfter = new List<String>() {"","-","Mc" };
                StringBuilder NameBuilder = new StringBuilder();
                name.Select(c => c.ToString()).ToList().ForEach(c =>
                {
                    c = c.ToLower();
                    new List<String>() {"","-","Mc" }.ForEach(s =>
                    {
                        if(String.IsNullOrEmpty(NameBuilder.ToString()) || NameBuilder.ToString().EndsWith(s))
                        {
                            c = c.ToUpper();
                        }
                    });
                    NameBuilder.Append(c);
                });
                return NameBuilder.ToString();
            }


    textinfo ti=cultureinfo.currentCulture.textinfo;console.writeline(ti.toitlecase(inputstring));


    1
    2
    3
    4
    5
    6
    7
    8
    9
    string s_Val ="test";
    if (s_Val !="")
    {
       s_Val  = char.ToUpper(s_Val[0]);
       if (s_Val.Length > 1)
       {
          s_Val += s_Val.Substring(1);
       }
     }


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    string input ="red HOUSE";
    System.Text.StringBuilder sb = new System.Text.StringBuilder(input);

    for (int j = 0; j < sb.Length; j++)
    {
        if ( j == 0 ) //catches just the first letter
            sb[j] = System.Char.ToUpper(sb[j]);
        else  //everything else is lower case
            sb[j] = System.Char.ToLower(sb[j]);
    }
    // Store the new string.
    string corrected = sb.ToString();
    System.Console.WriteLine(corrected);

    1
    2
    3
    4
    5
    6
    7
     private string capitalizeFirstCharacter(string format)
     {
         if (string.IsNullOrEmpty(format))
             return string.Empty;
         else
             return char.ToUpper(format[0]) + format.ToLower().Substring(1);
     }


    最简单和最快的方法是将字符串的第一个字符替换为大写字符:

    1
    2
    string str ="test";
    str = str.Replace(str[0], char.ToUpper(str[0]));