最初の文字をすべて大文字に変換し、単語ごとに小文字にする


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デザイナーの中には本当の意味で不快な人もいます。
ジョージマウアー

7
このメソッドは質問者が要求したことを実行しますが、どのような種類の単語であるかに関係なく、各単語を大文字にするだけの単純なアルゴリズムです。タイトルの大文字と小文字の規則は言語によって異なるため、実際には「タイトルのケース」ではありません。それは英語でも正しくありません。たとえば、「男の子について」というタイトルは英語では「男の子について」である必要がありますが、この方法では「男の子について」となります。あなたがしたい場合は、真のタイトルケースを、独自のメソッドを記述する必要があります。
ライアンランディ

18
私はそれらをジャークとは呼ばないでしょう。"ToTitleCase"は、カルチャに依存しているため、System.Globalization名前空間にある必要があります。CurrentThreadを通過するのは、スレッドの現在のカルチャーを取得するためだけです(ユーザーが別のロケールを使用している場合、これにより別の動作が発生する可能性があることに注意してください)。また、 "CultureInfo.InvariantCulture.TextInfo.ToTitleCase()"を実行することもできます。これは、すべてのカルチャでInvariantCultureが同じように動作するため、優れている場合があります。ジョージ:文化固有の文字列関数はどこに配置しますか?
Michael Stum

3
また、すべて大文字の文字列についてのコメントを注意してください。msdn.microsoft.com/en-us/library/...は
マイケルStum

2
メソッドtoLower()はToLower()である必要があります。メソッドの最初の文字は大文字で始まります
Alex

84

おそらく、Thread.CurrentThreadSystem.Threading)よりもCultureInfoSystem.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);
    }

2番目の方法(少し高速です)は、文字列を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 2017

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

9

Webページで使用している場合は、CSSを使用することもできます。

style="text-transform:capitalize;"


2
CSSを選ぶ理由 質問がc#asp.net regex
Jay

1
タグASP.NETは、OPがWEBで実行していることを示します。もちろん、これは問題の答えではありません。OPはソリューションを必要としたためですC#が、問題を解決し、代替ソリューションになる可能性があります。+1
ムハンマドサキブ2018

6

大きなテーブルを作成するときは速度が問題になるので、Jamie Dixonの2番目の関数が最適ですが、完全には機能しません...

それはすべての文字を小文字にすることに失敗し、文字列の各単語の最初の文字ではなく、文字列の最初の文字のみを大文字にします...以下のオプションは両方の問題を修正します:

    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

最初の回答に加えて、文字列selectionstartインデックスを単語の末尾に変更することを忘れないでください。そうしないと、文字列の文字の順序が逆になります。

s.SelectionStart=s.Length;

0

このテクニックを試してください。それは望ましい結果を返します

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

そして、使用することを忘れないでくださいSystem.Globalization


0

興味のある可能性のある解決策の1つ。1つのループで文字の配列を右から左に移動し、逆も同様です。

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.