Заглавные слова в строке с использованием С#
Мне нужно взять строку и загладить слова в ней. Определенные слова ( "in", "at" и т.д.) Не капитализируются и заменяются на нижний регистр, если они встречаются. Первое слово всегда должно быть заглавным. Последние имена, такие как "McFly", не входят в текущую область действия, поэтому к ним применимо одно и то же правило - только первая буква заглавная.
Например: "из мышей и мужчин по CNN" следует заменить на "Of Mice and Men by CNN". (Поэтому ToTitleString не будет работать здесь)
Мне интересно, что было бы лучшим способом сделать это.
То, о чем я думал, состоит в том, чтобы разделить строку пробелами и переходить через каждое слово, меняя его, если необходимо, и объединяет его с предыдущим словом и т.д.
Это кажется довольно наивным, и мне было интересно, есть ли лучший способ сделать это, используя .Net 3.5.
Ответы
Ответ 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);