web-dev-qa-db-ja.com

C#を使用して文字列内の単語を大文字にする

文字列を取得し、その中の単語を大文字にする必要があります。特定の単語(「in」、「at」など)は大文字ではなく、検出されると小文字に変更されます。最初の単語は常に大文字にする必要があります。 「McFly」のような姓は現在のスコープに含まれていないため、同じルールが適用されます。大文字の最初の文字のみです。

例:「CNNによる二十日鼠と人間」は「CNNによる二十日鼠と人間」に変更する必要があります。 (したがって、ToTitleStringはここでは機能しません

私はそれを行うための最良の方法は何でしょうか。私が考えたのは、文字列をスペースで分割し、各単語を調べ、必要に応じて変更し、前の単語に連結するなどです。かなりナイーブなようで、.Net3.5を使用してそれを行うためのより良い方法があるかどうか疑問に思いました。

21
Nir

大文字の使用を計画している頻度に応じて、私は素朴なアプローチを採用します。正規表現でそれを行うこともできますが、特定の単語を大文字にしたくないという事実は、それを少しトリッキーにします。

編集:

正規表現を使用して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つの表現でそれを実行できるほど十分ではありませんが、可能かもしれません。

16
jonnii

使用する

Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase("of mice and men By CNN");

固有名詞に変換すると、前述のようにキーワードをループできます。

16
dhinesh

ここに答えがあります 名前を大文字にする方法

CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
TextInfo textInfo = cultureInfo.TextInfo;

Console.WriteLine(textInfo.ToTitleCase(title));
Console.WriteLine(textInfo.ToLower(title));
Console.WriteLine(textInfo.ToUpper(title));
7
Vasyl Senko

最初にToTitleCase()を使用してから、該当する単語のリストを保持し、Replaceをそれらの該当する単語のすべて小文字のバージョンに戻します(リストが小さい場合)。

適用可能な単語のリストを辞書に保存し、かなり効率的にループして、同等の.ToLower()に置き換えることができます。

3
funkymushroom

次のようなものを試してください。

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"
2
m0sa

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");
1
ilan

無視したい単語を含む辞書を作成し、文をフレーズ(.split( ''))に分割し、フレーズごとに、そのフレーズが辞書に存在するかどうかを確認します。存在しない場合は、最初の文字を大文字にします。次に、文字列を文字列バッファに追加します。現在処理しているフレーズが辞書にある場合は、それを文字列バッファに追加するだけです。

1
npinti

単純なケースを処理する非賢いアプローチ:

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);
1
RedFilter

説明しているように、独自の関数を作成する必要があります。

0
slim

(英語の文章の)最も簡単な明白な解決策は次のとおりです。

  • "sentence".Split(" ")スペース文字の文
  • 各アイテムをループします
  • 各項目の最初の文字を大文字にします-item[i][0].ToUpper()
  • スペースで結合された文字列に再びマージします。
  • 「。」を使用してこのプロセスを繰り返します。そして「、」その新しい文字列を使用します。
0
Chris S