C# Строка с заглавными буквами, но только после определенных знаков препинания
Я пытаюсь найти эффективный способ взять входную строку и использовать заглавные буквы после каждого знака препинания (. : ? !
), за которым следует пробел.
Входные данные:
"Я что-то съел. Но я не сделал: вместо этого нет. Что вы думаете? Я думаю, что нет! Извините. Мой"
Выход:
"Я что-то съел. Но я не сделал. Вместо этого нет. Как вы думаете? Я думаю, что нет! Извините. Мой"
Очевидным было бы разделить его и затем использовать первый символ каждой группы с заглавной буквы, а затем объединить все. Но это безобразно. Какой лучший способ сделать это? (Я думаю Regex.Replace
используя MatchEvaluator
с большой буквы, но хотел бы получить больше идей)
Спасибо!
4 ответа
Попробуй это:
string expression = @"[\.\?\!,]\s+([a-z])";
string input = "I ate something. but I didn't: instead, no. what do you think? i think not! excuse me.moi";
char[] charArray = input.ToCharArray();
foreach (Match match in Regex.Matches(input, expression,RegexOptions.Singleline))
{
charArray[match.Groups[1].Index] = Char.ToUpper(charArray[match.Groups[1].Index]);
}
string output = new string(charArray);
// "I ate something. But I didn't: instead, No. What do you think? I think not! Excuse me.moi"
Быстро и просто:
static class Ext
{
public static string CapitalizeAfter(this string s, IEnumerable<char> chars)
{
var charsHash = new HashSet<char>(chars);
StringBuilder sb = new StringBuilder(s);
for (int i = 0; i < sb.Length - 2; i++)
{
if (charsHash.Contains(sb[i]) && sb[i + 1] == ' ')
sb[i + 2] = char.ToUpper(sb[i + 2]);
}
return sb.ToString();
}
}
Использование:
string capitalized = s.CapitalizeAfter(new[] { '.', ':', '?', '!' });
Я использую метод расширения.
public static string CorrectTextCasing(this string text)
{
// /[.:?!]\\s[a-z]/ matches letters following a space and punctuation,
// /^(?:\\s+)?[a-z]/ matches the first letter in a string (with optional leading spaces)
Regex regexCasing = new Regex("(?:[.:?!]\\s[a-z]|^(?:\\s+)?[a-z])", RegexOptions.Multiline);
// First ensure all characters are lower case.
// (In my case it comes all in caps; this line may be omitted depending upon your needs)
text = text.ToLower();
// Capitalize each match in the regular expression, using a lambda expression
text = regexCasing.Replace(text, s => (s.Value.ToUpper));
// Return the new string.
return text;
}
Тогда я могу сделать следующее:
string mangled = "i'm A little teapot, short AND stout. here IS my Handle.";
string corrected = s.CorrectTextCasing();
// returns "I'm a little teapot, short and stout. Here is my handle."
Используя маршрут Regex / MatchEvaluator, вы можете найти
"[.:?!]\s[a-z]"
и использовать весь матч с большой буквы.
Где текстовая переменная содержит строку
string text = "I ate something. but I didn't: instead, no. what do you think? i think not! excuse me.moi";
string[] punctuators = { "?", "!", ",", "-", ":", ";", "." };
for (int i = 0; i< 7;i++)
{
int pos = text.IndexOf(punctuators[i]);
while(pos!=-1)
{
text = text.Insert(pos+2, char.ToUpper(text[pos + 2]).ToString());
text = text.Remove(pos + 3, 1);
pos = text.IndexOf(punctuators[i],pos+1);
}
}