文字列を取得し、その中の単語を大文字にする必要があります。特定の単語(「in」、「at」など)は大文字ではなく、検出されると小文字に変更されます。最初の単語は常に大文字にする必要があります。 「McFly」のような姓は現在のスコープに含まれていないため、同じルールが適用されます。大文字の最初の文字のみです。
例:「CNNによる二十日鼠と人間」は「CNNによる二十日鼠と人間」に変更する必要があります。 (したがって、ToTitleStringはここでは機能しません)
私はそれを行うための最良の方法は何でしょうか。私が考えたのは、文字列をスペースで分割し、各単語を調べ、必要に応じて変更し、前の単語に連結するなどです。かなりナイーブなようで、.Net3.5を使用してそれを行うためのより良い方法があるかどうか疑問に思いました。
大文字の使用を計画している頻度に応じて、私は素朴なアプローチを採用します。正規表現でそれを行うこともできますが、特定の単語を大文字にしたくないという事実は、それを少しトリッキーにします。
編集:
正規表現を使用して2つのパスでそれを行うことができます
var result = Regex.Replace("of mice and men isn't By CNN", @"\b(\w)", m => m.Value.ToUpper());
result = Regex.Replace(result, @"(\s(of|in|by|and)|\'[st])\b", m => m.Value.ToLower(), RegexOptions.IgnoreCase);
Of Mice and Men Isn't by CNN
を出力します。
最初の式は単語境界のすべての文字を大文字にし、2番目の式は空白で囲まれたリストに一致するすべての単語を小文字にします。
このアプローチの欠点は、regexを使用していることであり(現在、2つの問題があります)、除外された単語のリストを最新の状態に保つ必要があります。私の正規表現は、1つの表現でそれを実行できるほど十分ではありませんが、可能かもしれません。
使用する
Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase("of mice and men By CNN");
固有名詞に変換すると、前述のようにキーワードをループできます。
ここに答えがあります 名前を大文字にする方法
CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
TextInfo textInfo = cultureInfo.TextInfo;
Console.WriteLine(textInfo.ToTitleCase(title));
Console.WriteLine(textInfo.ToLower(title));
Console.WriteLine(textInfo.ToUpper(title));
最初にToTitleCase()
を使用してから、該当する単語のリストを保持し、Replace
をそれらの該当する単語のすべて小文字のバージョンに戻します(リストが小さい場合)。
適用可能な単語のリストを辞書に保存し、かなり効率的にループして、同等の.ToLower()
に置き換えることができます。
次のようなものを試してください。
public static string TitleCase(string input, params string[] dontCapitalize) {
var split = input.Split(' ');
for(int i = 0; i < split.Length; i++)
split[i] = i == 0
? CapitalizeWord(split[i])
: dontCapitalize.Contains(split[i])
? split[i]
: CapitalizeWord(split[i]);
return string.Join(" ", split);
}
public static string CapitalizeWord(string Word)
{
return char.ToUpper(Word[0]) + Word.Substring(1);
}
複雑な姓を処理する必要がある場合は、後でCapitalizeWord
メソッドを更新できます。これらのメソッドをクラスに追加し、次のように使用します。
SomeClass.TitleCase("a test is a sentence", "is", "a"); // returns "A Test is a Sentence"
Jonniiの答えのわずかな改善:
var result = Regex.Replace(s.Trim(), @"\b(\w)", m => m.Value.ToUpper());
result = Regex.Replace(result, @"\s(of|in|by|and)\s", m => m.Value.ToLower(), RegexOptions.IgnoreCase);
result = result.Replace("'S", "'s");
無視したい単語を含む辞書を作成し、文をフレーズ(.split( ''))に分割し、フレーズごとに、そのフレーズが辞書に存在するかどうかを確認します。存在しない場合は、最初の文字を大文字にします。次に、文字列を文字列バッファに追加します。現在処理しているフレーズが辞書にある場合は、それを文字列バッファに追加するだけです。
単純なケースを処理する非賢いアプローチ:
var s = "of mice and men By CNN";
var sa = s.Split(' ');
for (var i = 0; i < sa.Length; i++)
sa[i] = sa[i].Substring(0, 1).ToUpper() + sa[i].Substring(1);
var sout = string.Join(" ", sa);
Console.WriteLine(sout);
説明しているように、独自の関数を作成する必要があります。
(英語の文章の)最も簡単な明白な解決策は次のとおりです。
"sentence".Split(" ")
スペース文字の文item[i][0].ToUpper()
、