모든 첫 글자를 대문자로 변환하고 각 단어에 대해 더 낮게 유지


110

변환해야하는 텍스트 문자열 (대부분 약 5-6 단어)이 있습니다.

현재 텍스트는 다음과 같습니다.

THIS IS MY TEXT RIGHT NOW

다음으로 변환하고 싶습니다.

This Is My Text Right Now

문자열 컬렉션을 반복 할 수 있지만이 텍스트 수정을 수행하는 방법을 모르겠습니다.

답변:


251
string s = "THIS IS MY TEXT RIGHT NOW";

s = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());

31
하하 정말? 그게 어디야? 저는 .NET을 좋아하지만 일부 API 디자이너는 진짜 바보입니다.
George Mauer

7
이 방법은 질문자가 요청한 것을 수행하지만 어떤 종류의 단어인지에 관계없이 각 단어를 대문자로 표시하는 순진한 알고리즘입니다. 제목 대소 문자에 대한 규칙은 언어마다 다르기 때문에 실제로 "제목 대소 문자"가 아닙니다. 영어에도 맞지 않습니다. 예를 들어, "About a Boy"라는 제목은 영어로 "About a Boy"여야하지만이 방법은 "About A Boy"를 제공합니다. 진정한 제목 케이스 를 원한다면 자신 만의 방법을 작성해야합니다.
Ryan Lundy

18
나는 그들을 바보라고 부르지 않을 것입니다. "ToTitleCase"는 문화에 따라 다르므로 System.Globalization 네임 스페이스에 있어야합니다. CurrentThread를 통과하는 것은 스레드의 현재 Culture를 얻기 위해 수행 된 것입니다 (사용자가 다른 로케일을 사용하는 경우 다른 동작이 발생할 수 있습니다!). InvariantCulture가 모든 문화권에서 동일하게 작동하므로 "CultureInfo.InvariantCulture.TextInfo.ToTitleCase ()"를 수행 할 수도 있습니다. 관심이없는 George : 문화 별 문자열 함수를 어디에 배치 하시겠습니까?
Michael Stum

3
모든 대문자 문자열에 대한 주석도 참고하십시오. msdn.microsoft.com/en-us/library/…
Michael Stum

2
메소드 tolower를은 () ToLower는 (), 대문자와 방법 시작의 첫 글자해야한다
알렉스

84

Thread.CurrentThread ( System.Threading ) 보다 CultureInfo ( System.Globalization ) 에서 ToTitleCase 를 호출하는 것을 선호합니다.

string s = "THIS IS MY TEXT RIGHT NOW";
s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());

하지만 jspcal 솔루션과 동일해야합니다.

편집하다

실제로 이러한 솔루션은 동일하지 않습니다 . CurrentThread--calls-> CultureInfo!


System.Threading.Thread.CurrentThread.CurrentCulture

string s = "THIS IS MY TEXT RIGHT NOW";
s = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());

IL_0000:  ldstr       "THIS IS MY TEXT RIGHT NOW"
IL_0005:  stloc.0     // s
IL_0006:  call        System.Threading.Thread.get_CurrentThread
IL_000B:  callvirt    System.Threading.Thread.get_CurrentCulture
IL_0010:  callvirt    System.Globalization.CultureInfo.get_TextInfo
IL_0015:  ldloc.0     // s
IL_0016:  callvirt    System.String.ToLower
IL_001B:  callvirt    System.Globalization.TextInfo.ToTitleCase
IL_0020:  stloc.0     // s

System.Globalization.CultureInfo.CurrentCulture

string s = "THIS IS MY TEXT RIGHT NOW";
s = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());

IL_0000:  ldstr       "THIS IS MY TEXT RIGHT NOW"
IL_0005:  stloc.0     // s
IL_0006:  call        System.Globalization.CultureInfo.get_CurrentCulture
IL_000B:  callvirt    System.Globalization.CultureInfo.get_TextInfo
IL_0010:  ldloc.0     // s
IL_0011:  callvirt    System.String.ToLower
IL_0016:  callvirt    System.Globalization.TextInfo.ToTitleCase
IL_001B:  stloc.0     // s

참조 :


16

문자열의 첫 번째 문자를 대문자로 변환하는 방법에는 두 가지가 있습니다.

첫 번째 방법은 첫 번째 문자를 간단히 캡핑하고 하위 문자열을 사용하여 나머지 문자열을 추가하는 메서드를 만드는 것입니다.

public string UppercaseFirst(string s)
    {
        return char.ToUpper(s[0]) + s.Substring(1);
    }

두 번째 방법 (약간 더 빠름)은 문자열을 char 배열로 분할 한 다음 문자열을 다시 빌드하는 것입니다.

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

1
이 솔루션은 질문에 정확히 대답하지 않습니다. 질문의 제목은 "모든 첫 글자를 대문자로 변환하고 각 단어에 대해 소문자로 변환"입니다. 그러나이 솔루션은 전체 문자열의 첫 글자 만 대문자로 표시합니다. 따라서이 솔루션은 "Hello World"가 아닌 "Hello World"로 "hello world"를 변환합니다.
brsfan

9

테스트되지 않았지만 다음과 같이 작동합니다.

var phrase = "THIS IS MY TEXT RIGHT NOW";
var rx = new System.Text.RegularExpressions.Regex(@"(?<=\w)\w");
var newString = rx.Replace(phrase,new MatchEvaluator(m=>m.Value.ToLowerInvariant()));

본질적으로 "다른 영숫자 문자 다음에 나오는 모든 영숫자 문자에 대해 정규식 일치를 미리 만든 다음 자체의 소문자 버전으로 대체"라고 말합니다.


이것은 또한 모든 대문자 단어가 대문자로 시작하고 소문자로 계속되도록 만듭니다. 내가 찾던 바로 그것.
M. Azyoksul 19.11.

9

웹 페이지에서 사용하는 경우 CSS를 사용할 수도 있습니다.

style="text-transform:capitalize;"


2
왜 CSS인가? 질문이 c # asp.net regex를
Jay

1
태그 ASP.NET는 OP가 WEB에서하고 있음을 보여줍니다. 물론 이것은 OP가 해결책을 필요로하기 때문에 질문의 답이 C#아니지만 문제를 해결하고 대안이 될 수 있습니다. +1
Muhammad Saqib

6

큰 테이블을 만드는 속도가 문제가 될 때 Jamie Dixon의 두 번째 기능이 가장 좋지만 완전히 작동하지는 않습니다.

모든 문자를 소문자로 바꾸는 데 실패하고 문자열의 각 단어의 첫 글자가 아닌 문자열의 첫 글자 만 대문자로 표시합니다 ... 아래 옵션은 두 문제를 모두 해결합니다.

    public string UppercaseFirstEach(string s)
    {
        char[] a = s.ToLower().ToCharArray();

        for (int i = 0; i < a.Count(); i++ )
        {
            a[i] = i == 0 || a[i-1] == ' ' ? char.ToUpper(a[i]) : a[i];

        }

        return new string(a);
    }

이 시점에서 이것이 여전히 가장 빠른 옵션인지 여부는 확실하지 않지만 RegexGeorge Mauer가 제공 하는 솔루션이 더 빠를 수 있습니다. 충분히 관심이있는 사람이 테스트해야합니다.


2
그것은 작동하지만, 나는이 "a.Count ()"a.Length로 변경
기독교

2

아래 솔루션이 jspcal의 답변보다 다소 효율적인지 모르겠지만 Jamie와 George보다 객체 생성이 덜 필요하다고 확신합니다.

string s = "THIS IS MY TEXT RIGHT NOW";
StringBuilder sb = new StringBuilder(s.Length);
bool capitalize = true;
foreach (char c in s) {
    sb.Append(capitalize ? Char.ToUpper(c) : Char.ToLower(c));
    capitalize = !Char.IsLetter(c);
}
return sb.ToString();

1
객체 생성에 관심이 있다면 StringBuilder를 사용하는 대신 s에 대한 for 루프 인덱싱을 사용하여 제자리에서 수행하지 않는 이유는 무엇입니까?
jball 2009

0

첫 번째 대답 외에도 문자열 선택 시작 색인을 단어의 끝으로 변경하는 것을 잊지 마십시오. 그렇지 않으면 문자열에서 문자의 역순을 얻게됩니다.

s.SelectionStart=s.Length;

0

이 기술을 시도하십시오. 원하는 결과를 반환합니다.

CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());

그리고 사용하는 것을 잊지 마십시오 System.Globalization.


0

관심이있을 수있는 가능한 솔루션 중 하나입니다. 하나의 루프에서 문자 배열을 오른쪽에서 왼쪽으로, 그 반대로 순회합니다.

public static string WordsToCapitalLetter(string value)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            throw new ArgumentException("value");
        }

        int inputValueCharLength = value.Length;
        var valueAsCharArray = value.ToCharArray();

        int min = 0;
        int max = inputValueCharLength - 1;

        while (max > min)
        {
            char left = value[min];
            char previousLeft = (min == 0) ? left : value[min - 1];

            char right = value[max];
            char nextRight = (max == inputValueCharLength - 1) ? right : value[max - 1];

            if (char.IsLetter(left) && !char.IsUpper(left) && char.IsWhiteSpace(previousLeft))
            {
                valueAsCharArray[min] = char.ToUpper(left);
            }

            if (char.IsLetter(right) && !char.IsUpper(right) && char.IsWhiteSpace(nextRight))
            {
                valueAsCharArray[max] = char.ToUpper(right);
            }

            min++;
            max--;
        }

        return new string(valueAsCharArray);
    }

0

문자열 확장으로 jspcal의 대답.

Program.cs

class Program
{
    static void Main(string[] args)
    {
        var myText = "MYTEXT";
        Console.WriteLine(myText.ToTitleCase()); //Mytext
    }
}

StringExtensions.cs

using System;
public static class StringExtensions
{

    public static string ToTitleCase(this string str)
    {
        if (str == null)
            return null;

        return System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.