使用c#在字符串中大写单词

我需要一个字符串,并在其中大写单词。 某些单词(“in”,“at”等)不会大写,如果遇到则会更改为小写。 第一个词应该总是大写。 像“McFly”这样的姓氏不属于当前范围,因此同样的规则适用于他们 – 只有首字母大写。

例如:“CNN的老鼠和男人”应改为“CNN的老鼠和男人”。 ( 因此ToTitleString在这里不起作用

我想知道最好的方法是什么。 我想到的是用空格分割字符串,然后遍历每个单词,必要时更改它,并将其连接到前一个单词,依此类推。 看起来很天真,我想知道是否有更好的方法,使用.Net 3.5。

根据您计划进行大写的频率,我会采用天真的方法。 你可以用正则表达式来做,但事实上你不希望某些单词大写,这使得它有点棘手。

编辑:

您可以使用正则表达式进行两次传递

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输出Of Mice and Men Isn't by CNN

第一个表达式将单词边界上的每个字母大写,第二个表达式下调任何与空格包围的列表匹配的单词。

这种方法的缺点是你正在使用正则表达式(现在你有两个问题),你需要保持排除的单词列表是最新的。 我的正则表达式不足以能够在一个表达式中完成它,但它可能是可能的。

使用

 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" 

您可以使用包含您要忽略的单词的词典,将短语(.split(”))中的句子拆分,并为每个短语检查词组中是否存在短语,如果不存在,则将第一个字符大写然后,将字符串添加到字符串缓冲区。 如果您当前正在处理的短语在字典中,只需将其添加到字符串缓冲区即可。

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

您应该像描述一样创建自己的函数。

处理简单案例的非聪明方法:

 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()
  • 重新回到连接在空间上的字符串。
  • 用“。”重复此过程。 和“,”使用新字符串。