문자열의 첫 글자를 대문자로 만듭니다 (성능 극대화).


448

나는이 DetailsViewA를을 TextBox 하고 내가 원하는 입력 데이터가 될 수 항상 저장 첫 글자 자본으로.

예:

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

최대 성능을 어떻게 달성 할 수 있습니까?


참고 :
답변과 답변 아래의 주석을 기반으로 많은 사람들은 이것이 문자열의 모든 단어를 대문자로 쓰는 것에 대해 묻는 것이라고 생각 합니다. 예를 들어 => Red House , 그렇지 않지만 그것이 원하는 경우TextInfoToTitleCase방법 을 사용하는 답변 중 하나를 찾으십시오 . (참고 : 이 질문에 대한 답변은 실제로 질문 한 내용에 맞지 않습니다 .) 주의 사항에
대해서는 TextInfo.ToTitleCase 문서 를 참조하십시오 (모두 대문자 단어를 건드리지 마십시오. 두문자어로 간주됩니다. 예 : "McDonald"=> "Mcdonald"; 모든 문화권의 미묘한 부분을 대문자로 처리한다는 보장은 없습니다.)


참고 :
질문은 모호한 처음 후에 문자가되어야하는지에 강제 하는 소문자 . 수락 된 답변은 첫 글자 만 변경해야 한다고 가정합니다 . 당신이 강제하려면 첫 번째를 제외하고 문자열의 모든 문자를 소문자로, 답변에 대한보기는 포함 ToLower하고 ToTitleCase을 포함하지 않는 .


7
@Bobby : 복제본이 아닙니다. OP는 문자열의 첫 글자를 대문자로 표시하고 링크의 질문은 각 단어의 첫 글자를 대문자로 표시합니다.
GvS

1
@GvS : 첫 번째 대답은 매우 상세하고 첫 번째 코드 블록은 정확히 그가 무엇을 찾고. 또한 모든 단어를 대문자로 바꾸는 것과 첫 단어 만 대문자로 바꾸는 것 사이에는 단 하나의 루프 차이가 있습니다.
Bobby

이 문제를 성공적으로 해결 한 적이 있습니까? 여전히 도움이 필요하십니까?
jcolebrand

1
그러나 당신은 말 했어요. "각 단어의 첫 글자를 대문자로 만드십시오." 그러므로 왜 "빨간 집"-> "빨간 집"? "집"의 "h"가 대문자가 아닌 이유는 무엇입니까?
Guillermo Gutiérrez

처음에 공백이 있으면 대부분의 답변이 실패하므로 답변을 추가했습니다. 각 답변에 이것을 게시하지 않으려면 여기에 한 번 게시합니다.
Noctis

답변:


583

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 : 아마도 가장 빠른 해결책은 Darren ( 아마도 벤치 마크가 있음) 일 것입니다. 그러나 string.IsNullOrEmpty(s)원래 요구 사항은 첫 글자가 존재할 것으로 예상되므로 대문자를 사용할 수 있기 때문에 예외를 던지는 유효성 검사를 변경합니다 . 이 코드는 일반 문자열에서 작동하며 특히 유효한 값은 아닙니다.Textbox .


2
의 첫 번째 매개 변수는 String.Join두 번째 매개 변수로 제공된 문자열을 결합 할 분리 문자 이기 때문 입니다.
Dialecticus

27
나는 당신의 대답을 정말로 좋아하지만 var arr = input.ToCharArray(); arr[0] = Char.ToUpperInvariant(arr[0]); return new String(arr);불변의 객체를 만들고 있기 때문에 (그리고 특히을 건너 뛰기 때문에 String.Join) 약간의 속도를 얻을 것입니다 . 이것은 물론 문자열의 길이에 따라 다릅니다.
flindeberg

3
굉장-Linq를 사용하면이 코드의 기능이 매우 명확 해집니다.
다니엘 제임스 Bryars

7
흠 ... 기술적으로 대문자 첫 글자 규칙에 맞게 돌아와야 "Argh!"합니다 . ;)
jp2code

2
@ jp2code null 또는 빈 문자열에 존재하지 않는 첫 글자를 대문자로 표기하는 것은 임신 한 돌고래가 때리는 것과 같으므로 ALL CAPS ARGH! 올바른 철자입니다. urbandictionary.com/define.php?term=ARGH&defid=67839
Carlos Muñoz

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

@GvS, 그것이 질문에서 요구하는 것입니다.
thattolleyguy

17
그는 "red house"=> "Red house"를 묻습니다. ToTitleCase는 "레드 하우스"를 제공합니다.
GvS

1
나에게 도움이되었습니다. 위대한
Ehsan Sajjad

1
확실하지 않지만 char + string은 권투를 유발합니다. 최대 성능이 필요한 경우를 대비하여.
nawfal

164

올바른 방법은 문화를 사용하는 것입니다.

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

참고 : 이렇게하면 문자열 내에서 각 단어를 대문자로 표시합니다 (예 : "red house"-> "Red House"). 이 솔루션은 "old McDonald"-> "Old Mcdonald"와 같은 단어 내에서 대문자를 사용합니다.


4
이것은 바퀴를 재발견하고 자신의 버전을 작성하는 것이 아니라 가장 적절한 방법입니다.
Alexey Shevelyov

12
내가 가진 문제는 문자열의 중간에 유효한 대문자를 지울 수 있다는 것입니다. 예 : McNames
Jecoms

29
이것은 "빨간색 집"이 "빨간색 집"이되는 이유에 대한 잘못된 대답입니다 ( "H"에 주목)!
spaark

21
질문을받은 후 6 년이 지나면 기존 답변과 의견을 자세히 읽어보십시오 . 더 나은 솔루션이 있다고 확신하면 답변이 우수하다고 생각되는 방식, 특히 기존 답변과 다른 방식으로 답변하는 상황 을 보여 주십시오. 1) Equiso는 이미 답변의 후반부 에서이 옵션을 다루었습니다. 2) ToLower"McDonalds"와 같이 대문자로 대문자를 지우는 경우가 많으 므로 실수입니다. 3) 질문에 관한 문자열의 바로 첫 번째 단어 변경 , 하지 타이틀 케이스에 대한합니다.
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가 첫 번째 문자를 요구하기 때문에 빈 문자열을 전달해도 예외가 발생한다고 주장합니다 . 또한 다른 사람의 답변을 편집하기 전에 주석을 달 수 있습니다.
Carlos Muñoz

@ CarlosMuñoz-다른 사람들의 답변을 "개선"할지 여부에 대해 메타에서 논의되었습니다. 합의는 "대답을 향상시킬 수 있다면, 그렇게 할 수 있습니다. 아무도 원작자도 대답을 '소유'하지 않습니다. 목표는 최상의 답변을 얻는 것입니다." 물론 편집 내용을 편집하거나 롤백 할 수 있습니다. 어떤 경우에, 일반적인 예의는 원저자 버전이 최종 결과가되게하고, 나는 의견을 제시 할 것이다. 보통 나는 또한 내가 하고있는 변화를 의견에 넣었다. 내가하지 않으면 사과드립니다.
ToolmakerSteve

@ CarlosMuñoz-특히 적극적으로 유지되지 않는 많은 답변이 있습니다. 변화가 답을 향상시킬 수 있다면 왜 코멘트에 묻어 두어야합니까? 저자가 적극적으로 답변을 모니터링하는 경우, 적절하다고 생각되는대로 변경 사항을 처리합니다. 그렇지 않은 경우 모든 사람의 이익에 대한 답변이 개선되었습니다. 이 원칙은 이와 같은 오래된 Q & A의 경우 특히 그렇습니다.
ToolmakerSteve

BTW, 나는 메소드 시작시 테스트에 대해 @ 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/2013/10/09/…를 참조하십시오
Vadim

1
이 솔루션은 두 가지 매우 다른 상황을 하나의 긴 방법으로 결합하기 때문에 마음에 들지 않습니다. 나는 개념적 이점도 보지 못합니다. 그리고 첫 글자 만 대문자로 구현하는 것은 우스운 일입니다. 첫 번째 문자를 대문자로 사용하려면 첫 번째 문자 를 대문자로 (ToUpper) 대문자로 구현 하십시오 . 대신에 두 가지 방법이 있습니다. FirstLetterToUpperEquiso의 답변 (또는 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);
    }

깨끗한 접근. 감사합니다!
Philippe

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

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

6

성능 / 메모리 사용이 문제인 경우,이 문자열은 원래 문자열과 동일한 크기의 StringBuilder 1 개와 새 String 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행은 본질적으로 동일 할 수 있습니다. :-)
Jonathan Gilbert

대런 (년 이후)를 사용하여이 작업을 수행하는 방법을 보여줍니다 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
snull 또는 비어있을 때 매개 변수를 반환하는 것이 좋습니다 .
MatrixRonny

4

이 시도:

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

2
또는 다른 문자 클래스 (예 : 영숫자 \ w)를 사용하여 함수가 유니 코드를 인식하도록
Dmitry Ledentsov

@ 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

나는 여기 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);
}

어쩌면 이것이 도움이 될 것입니다!


이것이 4 년 전 Equiso의 답변에 비해 어떻게 개선 되었습니까?
ToolmakerSteve

3

문자열이 null이 아닌지 확인한 다음 첫 번째 문자를 대문자로, 나머지는 소문자로 변환하십시오.

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
sToTitleCase를 호출하기 전에 null 검사가 필요합니다 .
Taras Alenin

@ CarlosMuñoz tlhIngan Hol의 스크립트에는 소문자가 없습니다. :-)
Jonathan Gilbert

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. String.IsNullOrWhiteSpace 는 .NET Framework 4에서 도입되었습니다. 이전 프레임 워크에서는 작동하지 않습니다.


1
나는 이것이 4 년 전의 원래 받아 들여진 대답에서 어떻게 개선되는지 알지 못합니다. 사실은 일관성이 새로운를 사용하는 경우에만 혜택 (소득 그래서하지만 사년 후반, 나는 새 응답 추가 이익을위한 높은 기준을 가지고) 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 () ?. 첫 글자 외에 다른 글자는 요구되지 않습니다.
Carlos Muñoz

String무엇이든 할 수있다 자사의 Upper또는 Lower모든 문자열에 대한 일반적인 솔루션 .so를.
Shailesh

Join대신에 emp.First().ToString().ToUpper() + emp.Substring(1);? 아마도 더 방어 적이어야 할 것입니다 : output = string.IsNullOrEmpty(emp) ? string.Empty : [...]. 또한 fwiw는 @ CarlosMuñoz에 동의합니다 ToLower(). OP 질문에 대해서는 필요하지 않습니다 .
ruffin

@ ruffin-> using Substring 은 코드 작성 스타일도 우수합니다. 코드 를 자르는 솔루션에 동의하지만이 경우에는 작성하는 ToLower()것이 좋습니다. string아무것도 할 수있다 Upper케이스 또는 Lower케이스가 사용자의 입력에 따라 달라집니다, 나는 일반적인 솔루션을 제공합니다.
Shailesh

@Shailesh-그러나 질문은 첫 글자 대문자를 요구 하지 않았습니다 . 첫 글자를 대문자로 바꾸라고 요청했다. 저자의 추가 설명이 없으면 가장 자연스러운 가정은 나머지 줄이 변경되지 않는다는 것입니다. 당신이 대답하는 것을 감안하면 3 년 후에 는 가정하십시오 허용 답변을 요청 애 스커 무엇 않습니다. 다르게 기술적 인 이유가있는 경우에만 다른 답변을 제공하십시오.
ToolmakerSteve

1

"최대 성능"답변을 제공하고 싶었습니다. 제 생각에는 "최대 성능"답변이 모든 시나리오를 포착하고 해당 시나리오에 대한 질문 설명에 대한 답변을 제공합니다. 그래서, 여기 내 대답이 있습니다. 이러한 이유로

  1. IsNullOrWhiteSpace는 공백이거나 널 / 빈인 문자열을 설명합니다.
  2. .Trim ()은 문자열의 앞뒤에서 공백을 제거합니다.
  3. .First ()는 ienumerable (또는 string)의 첫 문자를 사용합니다.
  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
이것은 대부분의 경우에 적용되지만 각 작업으로 생성되는 문자열 수를 고려하면 다소 느리지 않습니까? 여기에는 많은 문자열 할당이 있습니다. 바람직하게는 한 번, 한 번만 할당됩니다.
Douglas Gaskell

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의 코드를 사용하는 것이 좋습니다. 다른 문자열 조작을 통합하려면 입력 문자열의 문자를 터치하는 람다 함수의 표현력을 갖는 것이 편리 할 수 ​​있습니다.이 기능을 쉽게 확장 할 수 있으므로이 솔루션을 여기에 남겨 둡니다.


나는이 문제를 어떻게 해결하고 내 자신의 해결책을 찾은 다음 다시 게시하여 내가 이미 가지고있는 것과 똑같은 해결책을 찾았다는 것을 알게되었습니다. 당신에게 +1!
BlueFuzzy

대단히 감사합니다.
그림

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의 버전을 사용 Span하여 가비지를 줄이고 속도를 약 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);
        }
    }

}

편집 : s [0] 대신에 typeo가 a [0]이었습니다.이 결과는 할당 된 Span a에 동일한 빈 값을 cupying합니다.


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

그래 ... 난 몰랐어
thattolleyguy

추천 : 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(문장에 공백이 있음). 공간 트리밍이 마음에 들지 않으면 false두 번째 매개 변수로 전달하십시오 (또는 기본값을으로 변경하고 공백을 처리하려면 false전달 true하십시오)



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의 의견은 크레딧을주지 않으면 서 zamoldar가 표절 된 것 같습니다. 그 소스 링크를 제공하고 토론을 개선했기 때문에 나는 이에 대한 비판에도 불구하고이 답변을지지하고 있습니다.
ToolmakerSteve

1
Darian, 두 가지 개선이 가능합니다. 1) char.IsWhiteSpace( array[ i -1 ] )대신 .. == ' '공백을 사용 하여 공백을 처리하십시오. 2) 두 곳을 제거하십시오 if (char.isLower(..))-목적이 없습니다. ToUpper문자가 소문자가 아닌 경우 아무 것도 수행하지 않습니다.
ToolmakerSteve

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();
   }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.