Подтвердить что ты не робот

Заглавные слова в строке с использованием С#

Мне нужно взять строку и загладить слова в ней. Определенные слова ( "in", "at" и т.д.) Не капитализируются и заменяются на нижний регистр, если они встречаются. Первое слово всегда должно быть заглавным. Последние имена, такие как "McFly", не входят в текущую область действия, поэтому к ним применимо одно и то же правило - только первая буква заглавная.

Например: "из мышей и мужчин по CNN" следует заменить на "Of Mice and Men by CNN". (Поэтому ToTitleString не будет работать здесь)

Мне интересно, что было бы лучшим способом сделать это. То, о чем я думал, состоит в том, чтобы разделить строку пробелами и переходить через каждое слово, меняя его, если необходимо, и объединяет его с предыдущим словом и т.д. Это кажется довольно наивным, и мне было интересно, есть ли лучший способ сделать это, используя .Net 3.5.

4b9b3361

Ответ 1

В зависимости от того, как часто вы планируете делать капитализацию, я бы пошел с наивным подходом. Вы могли бы сделать это с регулярным выражением, но тот факт, что вы не хотите, чтобы некоторые слова были заглавные, делает это немного сложнее.

Изменить:

Вы можете сделать это с помощью двух проходов с использованием регулярных выражений

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.

Первое выражение заглаживает каждую букву на границе слова, а второе сокращает любые слова, соответствующие списку, окруженным пробелами.

Недостатки этого подхода заключаются в том, что вы используете регулярные выражения (теперь у вас есть две проблемы), и вам нужно постоянно обновлять список исключенных слов. Мой regex-fu недостаточно хорош, чтобы иметь возможность сделать это в одном выражении, но это возможно.

Ответ 2

Использование

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

чтобы преобразовать в правильный случай, а затем вы можете прокручивать ключевые слова, как вы уже упоминали.

Ответ 3

Вот ответ Как заглавные имена

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

Console.WriteLine(textInfo.ToTitleCase(title));
Console.WriteLine(textInfo.ToLower(title));
Console.WriteLine(textInfo.ToUpper(title));

Ответ 4

Почему бы не использовать ToTitleCase() сначала, а затем сохранить список применимых слов и Replace обратно к версии всех применимых слов (если этот список невелик).

Список применимых слов можно сохранить в словаре и проделать довольно эффективно, заменив эквивалентом .ToLower().

Ответ 5

Попробуйте что-то вроде этого:

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"

Ответ 6

У вас может быть словарь с словами, которые вы хотели бы игнорировать, разделить предложение на фразы (.split('')) и для каждой фразы проверить, существует ли фраза в словаре, если это не так, капитализировать первый символ, а затем добавьте строку в строковый буфер. Если фраза, которую вы сейчас обрабатываете, находится в словаре, просто добавьте ее в строковый буфер.

Ответ 7

Небольшое улучшение ответа 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");

Ответ 8

Вы должны создать свою собственную функцию, как вы описываете.

Ответ 9

Самым простым очевидным решением (для английских предложений) было бы следующее:

  • "sentence".Split(" ") предложение о символах пробела
  • Прокрутка каждого элемента
  • Используйте первую букву каждого элемента - item[i][0].ToUpper(),
  • Вернитесь обратно в строку, связанную с пробелом.
  • Повторите этот процесс с помощью "." и "," используя эту новую строку.

Ответ 10

Непродуманный подход, который обрабатывает простой случай:

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