使字符串的首字母大写(具有最佳性能)


447

我有DetailsView一个TextBox 和我想要的输入数据始终保存的第一个字母注册资本。

例:

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

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


注意
根据答案和答案下的注释,许多人认为这是在问是否要大写字符串中的所有单词。例如=> Red House ,不是这样,但是如果您要寻找的是,请寻找使用TextInfoToTitleCase方法的答案之一。(注意:这些答案对于实际提出的问题是不正确的。)
请参见TextInfo.ToTitleCase文档进行警告(不要触摸全大写字母的单词-它们被视为首字母缩写词;可以在单词中间用小写字母表示“不应”)降低,例如“ McDonald” =>“ Mcdonald”;不保证处理所有特定于文化的细微之处重新大写。)



现在的问题是含糊不清,是否后的第一个字母应该被迫小写。接受的答案假定只应更改第一个字母。如果您想强制,除了第一个字符串中的所有字母是小写,寻找一个答案包含ToLower不包含ToTitleCase


7
@Bobby:这不是重复的:OP要求将字符串的首字母大写,链接中的问题将每个单词的首字母大写。
GvS

1
@GvS:第一个答案非常详细,第一个代码块正是他正在寻找的东西。同样,在大写每个单词和仅第一个单词之间仅存在一个循环差异。
鲍比(Bobby)

您是否成功解决了这个问题?您还需要帮助吗?
jcolebrand 2010年

1
但是您说过,我引用“使每个单词的首字母大写”。因此,为什么要“红房子”->“红房子”?为什么“ house”的“ h”不是大写字母?
GuillermoGutiérrez2012年

添加了一个答案,因为如果开头有空格,大多数答案将失败。为了避免在每个答案上发布此内容,我将在此处将其发布一次。
2014年

Answers:


581

更新到C#8

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

C#7

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);
        }
    }
}

真的是老答案

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的答案

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

编辑2:最快的解决方案可能是达伦的解决方案(甚至有一个基准),尽管我会更改它的string.IsNullOrEmpty(s)验证以引发异常,因为最初的要求要求存在第一个字母,以便可以将其大写。请注意,此代码适用于通用字符串,而不适用于的有效值Textbox


2
因为of的第一个参数String.Join是分隔符,用于连接第二个参数给定的字符串。
Dialecticus 2012年

27
我真的很喜欢您的答案,但是var arr = input.ToCharArray(); arr[0] = Char.ToUpperInvariant(arr[0]); return new String(arr);由于您正在创建不可变的对象(尤其是跳过String.Join),因此可能会提高速度。当然,这取决于字符串的长度。
flindeberg 2013年

3
太棒了-使用Linq可以很清楚地看到此代码的作用。
Daniel James Bryars 2013年

7
嗯...从技术上讲,应该"Argh!"大写“首字母”规则保持一致。;)
jp2code 2015年

2
@ jp2code由于将大写的空或空字符串中的第一个字母大写就像被怀孕的海豚拍打一样,所以全部大写了!是正确的拼写。urbandictionary.com/define.php?term=ARGH&defid=67839
卡洛斯·穆尼奥斯(

319
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();
}

旧答案:这会使每个首字母大写

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

但这会将单词的每个首字母转换为大写,而不仅是字符串的首字符。
GvS 2010年

@GvS,这就是问题要您执行的操作。
thattolleyguy 2010年

17
他问“红房子” =>“红房子”。ToTitleCase将给您“红楼”。
GvS 2010年

1
对我有帮助 很棒
Ehsan Sajjad 2015年

1
对此不确定,但是char + string导致拳击。以防万一需要最大性能。
nawfal

162

正确的方法是使用文化:

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

注意:这将大写字符串中的每个单词,例如“ red house”->“ Red House”。该解决方案还将在单词中使用小写大写,例如“ Old McDonald”->“ Old Mcdonald”。


4
这是最合适的方法,而不是重新发明轮子并尝试编写自己的版本。
阿列克谢·谢维廖夫

12
我的问题是,它将擦除字符串中间的潜在有效大写字母。例如McNames
Jecoms

29
这是不正确的答案,原因是“红房子”变为“红房子”(请注意“ H”)!
spaark

21
提出问题六年后,请做更彻底的工作来阅读现有的答案及其评论。如果你确信你有一个更好的解决方案,然后显示在你想办法你的答案的行为是优越的情况下,特别是如何从现有的答案是不同的。1)Equiso在他的回答的后半部分已经介绍了此选项。2)在许多情况下,这ToLower是一个错误,因为它会消除单词中间的大写字母,例如“麦当劳”。3)问题是关于仅更改字符串的第一个单词而不是关于TitleCase。
ToolmakerSteve

10
这将输入变成“标题大小写”,因此将“红马”变成“红马”,而有人明确要求不要这样做(并返回“红马”)。这不是正确的方法。
Hekkaryk

68

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

    /// <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分配了一个字符串,而该方法为子字符串分配了一个字符串,然后分配了第二个字符串来构成最终结果。


编辑:这是这种方法的外观,再加上CarlosMuñoz接受的初始测试的答案

    /// <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);
    }

哇,感谢您找到性能指标,以展示性能卓越的解决方案!
ToolmakerSteve

@ToolmakerSteve,我喜欢这个解决方案,因为它确实确实比其他解决方案快,但是这样做有点问题。如果传递null,则不应获得空字符串作为输出。实际上,我会争辩说,即使传递空字符串也应该引发异常,因为OP要求输入第一个字母。另外,您可以在编辑其他人的答案之前对其进行评论。
卡洛斯·穆尼奥斯

@CarlosMuñoz-已经在meta中讨论了是否“改善”其他人的答案。共识是“如果您可以改善答案,那么就这样做-没有人'拥有'一个答案,甚至没有原始作者也没有-目标是要获得最佳答案”。您当然可以自由编辑或回滚编辑。在这种情况下,出于礼貌,将使原始作者的版本成为最终结果,我将发表评论。通常,我还会在注释中说明正在做出的更改;如果没有,我深表歉意。
ToolmakerSteve

@CarlosMuñoz-特别是,SO中有很多答案没有得到积极维护。如果更改可以改善答案,为什么还要在评论中留下答案呢?如果作者积极地监视他们的答案,他们将按照自己认为合适的方式进行更改。如果不是这样,那么答案就已经改善了,对每个人都有利。对于诸如此类的旧问答,这一原理尤其正确。
ToolmakerSteve

顺便说一句,对于方法开始时的测试,我同意@CarlosMuñoz的看法-他的测试版本是更好的编程风格- return string.Empty此处将隐藏对该方法的“错误”调用。
ToolmakerSteve

46

您可以使用“ ToTitleCase方法”

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

这种扩展方法可以解决所有标题问题。

易于使用

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

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

扩展方法

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
    }
}

您解决方案的问题是,“红房子”将转换为“红房子”,而不是问题中所要求的“红房子”。
Vadim

3
@Tacttin它将起作用,但以下代码更易于阅读并且性能更好char.ToUpper(text [0])+((text.Length> 1)?text.Substring(1).ToLower():string.Empty) ; 您可以阅读更多@ vkreynin.wordpress.com
Vadim

1
我不喜欢这种解决方案,因为它将两种截然不同的情况结合在一起,成为一种冗长的方法。我也看不到任何概念上的好处。而且仅首字母大写的实现是可笑的。如果要大写第一个字母,显而易见的实现是仅大写(ToUpper)第一个字母。取而代之的是,我将有两种单独的方法。FirstLetterToUpper在Equiso的答案中(或在Guillernet的较新答案中),ToTitleCase这里没有第二个参数。那就不用了enum TitleCase
ToolmakerSteve

31

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

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);
}

这和方便的扩展名一样

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);
    }

干净的方法。谢谢!
菲利普

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

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

6

如果性能/内存使用成为问题,那么此函数仅创建一(1)个StringBuilder和一(1)个新字符串,其大小与原始字符串相同。

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;
}

3
这可以通过简单的方法来完成,char[]而不必具有StringBuilder包装的所有基础结构。代替new StringBuilder(str)使用str.ToCharArray(),而不是sb.ToString()使用new string(charArray)StringBuilder模拟字符数组本机公开的索引类型,因此实际.ToUpper行可以基本相同。:-)
乔纳森·吉尔伯特

达伦(一年后)展示了如何做到这一点使用ToCharArray,如@JonathanGilbert建议
ToolmakerSteve

6

最快的方法。

  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
我建议s在为null或为空时返回参数。
MatrixRonny19年

4

尝试这个:

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

2
或某些其他字符类(即字母数字\ w),以便该函数可
识别

@ DmitryLedentsov- C#字符串类基于UTF-16字符构建。字符串类 “将文本表示为UTF-16代码单元的序列。”
ToolmakerSteve

4

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

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

我们需要转换第一个字符ToString(),因为我们将其读取为Char数组,并且Char类型没有ToUpper()方法。


3

这是将其作为扩展方法的一种方法:

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;
}

然后可以这样称呼:

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

这是一些单元测试:

[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);
}

1
string.Format太过分了 简单地做text.Substring(0, 1).ToUpper() + text.Substring(1)
ToolmakerSteve

3

由于我碰巧也在从事此工作,并且一直在寻找任何想法,因此这就是我的解决方案。它使用LINQ,并且即使首字母不是字母,也可以将首字母大写。这是我最终制作的扩展方法。

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);
}

我敢肯定有一种方法可以对此进行优化或清理。



3

检查字符串是否不为空,然后将第一个字符转换为大写,并将其余字符转换为小写:

public static string FirstCharToUpper(string str)
{
    return str?.First().ToString().ToUpper() + str?.Substring(1).ToLower();
}

感谢您提供小型解决方案,而不是仅仅为一个字符串单词准备几行代码!
Imran Faruqi

2

尽管可以做到这一点,但它也可以确保没有出现在单词开头的错误大写字母。

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);
}

2
s在调用ToTitleCase之前需要对null进行检查。
塔拉斯·阿列宁

@CarlosMuñoztlhIngan Hol的脚本中没有字母大写。:-)
乔纳森·吉尔伯特

2

当您需要的是:时,这里似乎有很多复杂性:

    /// <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);
    }

值得注意的几点:

  1. 它是一种扩展方法。

  2. 如果输入为null,空白或空白,则按原样返回输入。

  3. .NET Framework 4中引入了String.IsNullOrWhiteSpace。这不适用于较旧的框架。


1
我看不出这是对四年前最初接受的答案的改进。实际上,这是不一致的(无害,但迟到了四年,我对提高收益的新答案有了高标准):使用更新的IsNullOrWhiteSpace而不是的唯一好处IsNullOrEmpty是,如果您要查找并更改第一个非-空格。但是你不会-你总是在努力s[0]。因此使用它毫无意义(在语义和性能上)IsNullOrWhiteSpace
ToolmakerSteve

...这种用法IsNullOrWhiteSpace困扰我的原因是,一个粗心的读者可能会认为“他检查了空格,因此以下代码确实找到并更改了一个字母,即使该字母前面有空格也是如此”。由于您的代码将无法更改以空格开头的“第一个”字母,因此使用IsNullOrWhiteSpace只会误导读者。
ToolmakerSteve

…糟糕,我不是说已接受的答案,而是同一时期内Equiso的答案
ToolmakerSteve

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

为什么在尾部使用ToLower()?除第一个字母外,不需要其他字母。
卡洛斯·穆尼奥斯

String是可以是任何东西,它Upper还是Lower。所以其所有的字符串一个通用的解决方案。
Shailesh 2013年

为什么要Join代替emp.First().ToString().ToUpper() + emp.Substring(1);?可能还需要更加防御:output = string.IsNullOrEmpty(emp) ? string.Empty : [...]。另外,请与@CarlosMuñoz同意-您不需要ToLower()OP的问题。
鲁芬,2015年

@ ruffin->使用Substring 也是很好的代码编写风格,我同意您的解决方案,以修剪代码,但在这种情况下,编写 ToLower()好的编程习惯。string可以是任何Upper情况,Lower如果情况取决于用户输入,我会给出一个通用的解决方案。
Shailesh

@Shailesh-但是,该问题并没有要求首字母大写。它要求将第一个字母改为大写。未经作者进一步澄清,最自然的假设是字符串的其余部分保持不变。鉴于三年后您要回答,请假定接受的答案符合要求者的要求。仅在出于某种技术原因而采取不同的方式时才给出不同的答案。
ToolmakerSteve

1

我想提供一个“最大性能”的答案。在我看来,“最大性能”答案涵盖了所有情况,并为解决这些情况的问题提供了答案。所以,这是我的答案。由于这些原因:

  1. IsNullOrWhiteSpace将字符串解释为只是空格或null / empty。
  2. .Trim()从字符串的前面和后面删除空格。
  3. .First()采用可枚举(或字符串)的第一个字符。
  4. 我们应该检查它是否可以/应该是大写字母。
  5. 然后,仅在长度指示应添加字符串时,才添加其余字符串。
  6. 通过.Net最佳实践,我们应该在System.Globalization.CultureInfo下提供一种文化。
  7. 将它们提供为可选参数使该方法完全可重用,而不必每次都键入所选区域性。

    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;
    }

2
尽管这涵盖了大多数情况,但是考虑到每个操作创建的字符串数量,它会不会很慢?这里有大量的字符串分配。优选地,它将被分配一次,并且仅被分配一次。
道格拉斯·加斯凯尔

1

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

string input;
string output;

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

由于我经常需要这种方法,因此我为字符串类型做了一个扩展方法:

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));
    }
}

请注意,只有第一个字母会转换为大写字母-其余所有字符都不会被触摸。如果您需要其他字符为小写字母,则也可以为索引> 0调用Char.ToLower(currentChar)或首先对整个字符串调用ToLower()。

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


我想知道如何解决这个问题,制定自己的解决方案,然后回过头来发布它,结果发现您已经提出了与我已经完全相同的解决方案。+1给你!
BlueFuzzyThing

非常感谢你。
格林

1

我认为以下方法是最好的解决方案

    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

参考


1

因为这个问题是关于最大化性能,所以我采用了Darren版本来使用Spans,它减少了垃圾并提高了速度约10%。

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

            Span<char> a = stackalloc char[s.Length];
            s.AsSpan(1).CopyTo(a.Slice(1));
            a[0] = char.ToUpper(s[0]);
            return new string(a);
        }

性能

|  Method |      Data |      Mean |     Error |    StdDev |
|-------- |---------- |----------:|----------:|----------:|
|  Carlos |       red | 107.29 ns | 2.2401 ns | 3.9234 ns |
|  Darren |       red |  30.93 ns | 0.9228 ns | 0.8632 ns |
| Marcell |       red |  26.99 ns | 0.3902 ns | 0.3459 ns |
|  Carlos | red house | 106.78 ns | 1.9713 ns | 1.8439 ns |
|  Darren | red house |  32.49 ns | 0.4253 ns | 0.3978 ns |
| Marcell | red house |  27.37 ns | 0.3888 ns | 0.3637 ns |

完整的测试代码

using System;
using System.Linq;

using BenchmarkDotNet.Attributes;

namespace CorePerformanceTest
{
    public class StringUpperTest
    {
        [Params("red", "red house")]
        public string Data;

        [Benchmark]
        public string Carlos() => Data.Carlos();

        [Benchmark]
        public string Darren() => Data.Darren();

        [Benchmark]
        public string Marcell() => Data.Marcell();
    }

    internal static class StringExtensions
    {
        public static string Carlos(this string input) =>
            input switch
            {
                null => throw new ArgumentNullException(nameof(input)),
                "" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)),
                _ => input.First().ToString().ToUpper() + input.Substring(1)
            };

        public static string Darren(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);
        }

        public static string Marcell(this string s)
        {
            if (string.IsNullOrEmpty(s))
                throw new ArgumentException("There is no first letter");

            Span<char> a = stackalloc char[s.Length];
            s.AsSpan(1).CopyTo(a.Slice(1));
            a[0] = char.ToUpper(s[0]);
            return new string(a);
        }
    }

}

编辑:有一个typeo,而不是s [0],是a [0]-结果与分配的Span a相同,空值相同。


0

这会将第一个字母和每个字母大写,后跟一个空格,并将其他任何字母都小写。

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
或者,如果您不想编写代码墙-CultureInfo.CurrentCulture.TextInfo.ToTitleCase(theString); 做同样的事情。
Chev 2010年

是的...我对此一无所知:)由于我的代码量很大,所以在我仍在打字时弹出了其他所有人的答案。
thattolleyguy 2010年

支持:1)此答案与ToTitleCase之间的细微差别是,此答案将所有大写的单词都变成了TitleCase,而ToTitleCase则不理会这些单词(假设它们可能是首字母缩写词)。这可能是,也可能不是。具有这样的代码示例的一个优点是,可以根据需要对其进行修改。2)这不会正确处理''以外的空白。应该用空白测试代替空白测试。
ToolmakerSteve

0

使用以下代码:

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

我的代表多年后不再投票赞成这个答案,这甚至不值得一提,这显然等同于已经存在的答案。如果您要为包含许多答案的问题添加新答案,请说明您认为对您的答案更优越的答案,或者在什么情况下您的答案比其他答案更有用。请明确点。
ToolmakerSteve

0

似乎这里给出的解决方案都不会在字符串之前处理空格。

只是将此添加为一个想法:

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(该句子的开头有一个空格),如果您不喜欢空格修剪,只需将falseas作为第二个参数传递(或将默认值更改为falsetrue如果要处理空格则通过)



0

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

1-使用Sytem.Globalization;

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

  myTI.ToTitleCase(textboxname.Text)

`


1
这个答案与几年前给出的答案基本相同。它没有增加任何讨论。
ToolmakerSteve

这也是错误的,就像在另一个注释中一样,这将所有单词中的每个第一个字母变成大写,而不是用红房子代替红房子。
DeadlyChambers

0

以下功能在所有方面都是正确的:

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);
}

我发现在这里


为什么?当已经有太多看起来相似的答案时,为什么还要添加另一个答案所有现有答案有什么问题,促使您添加另一个答案?
ToolmakerSteve

因为此answare在所有方面都是正确的。别紧张。

对不起; 我不必要地苛刻。我会坚持以下事实:1)这与7年前thattolleyguy的回答基本相同。2)这与答案有相同的缺陷:除空白字符外,不处理空白。3)这回答的问题与OP提出的问题略有不同。如果您希望所有单词的首字母大写,请使用这样的答案。4)通常,最简单的方法是使用TitleInfo.ToTitleCase。(另一方面,代码示例的优势是可以根据需要进行自定义。)
ToolmakerSteve

纠正自己:这与thattolleyguy的方法不同:它留下的原封不动的字母不是单词的第一个字母。相反,它是一个重复zamoldar的答案。有利的是,赞扬达里安(Darian)给出了与消息源的链接 -似乎萨莫达尔窃而没有给予任何荣誉。由于提供了源链接,从而改善了讨论范围因此尽管我对此提出了批评,我还是赞成这个答案。
ToolmakerSteve

1
Darian可以进行两项改进:1)使用char.IsWhiteSpace( array[ i -1 ] )代替.. == ' '来处理所有空白。2)删除这两个地方if (char.isLower(..))-它们没有用。ToUpper如果字符不是小写字母,则根本不执行任何操作。
制造商史蒂夫

0

扩展上面的Carlos问题,如果您想将多个句子都大写,可以使用以下代码:

    /// <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; 
    }

0

解决您的问题的可能解决方案。

   public static string FirstToUpper(this string lowerWord)
   {
       if (string.IsNullOrWhiteSpace(lowerWord) || string.IsNullOrEmpty(lowerWord))
            return lowerWord;
       return new StringBuilder(lowerWord.Substring(0, 1).ToUpper())
                 .Append(lowerWord.Substring(1))
                 .ToString();
   }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.