22

我需要一个字符串,并将其中的单词大写。某些单词(“in”、“at”等)不大写,如果遇到则更改为小写。第一个单词应始终大写。像“McFly”这样的姓氏不在当前范围内,所以同样的规则将适用于他们——只有首字母大写。

例如:“of mouse and men By CNN”应改为“Of Mice and Men by CNN”。(因此 ToTitleString 在这里不起作用。)

最好的方法是什么?

我想用空格分割字符串,然后检查每个单词,如有必要进行更改,然后将其连接到前一个单词,依此类推。这似乎很天真,我想知道是否有更好的方法来做到这一点。我正在使用 .NET 3.5。

4

10 回答 10

20

采用

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

转换为正确的大小写,然后您可以循环遍历您提到的关键字。

于 2010-11-30T15:50:32.503 回答
19

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

您可以使用正则表达式通过两次传递来做到这一点:

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 不够好,无法在一个表达式中做到这一点,但它可能是可能的。

于 2010-11-30T15:48:58.167 回答
8

另一个问题的答案,如何大写名称-

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

Console.WriteLine(textInfo.ToTitleCase(title));
Console.WriteLine(textInfo.ToLower(title));
Console.WriteLine(textInfo.ToUpper(title));
于 2013-03-05T16:09:31.723 回答
4

首先使用ToTitleCase(),然后保留一个适用词的列表,然后Replace返回这些适用词的全小写版本(前提是该列表很小)。

适用单词的列表可以保存在字典中,并且可以非常有效地循环,替换为.ToLower()等效单词。

于 2010-11-30T15:54:08.997 回答
2

尝试这样的事情:

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"
于 2010-11-30T15:58:50.573 回答
2

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");
于 2014-02-06T11:46:57.043 回答
1

最简单明显的解决方案(对于英语句子)是:

  • "sentence".Split(" ")关于空格字符的句子
  • 循环遍历每个项目
  • 每个项目的第一个字母大写 - item[i][0].ToUpper(),
  • 重新合并为连接在空格上的字符串。
  • 用“.”重复这个过程 和 "," 使用该新字符串。
于 2010-11-30T15:49:19.337 回答
1

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

于 2010-11-30T15:50:57.403 回答
1

处理简单情况的非聪明方法:

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);
于 2010-11-30T15:53:13.893 回答
0

您应该像您描述的那样创建自己的功能。

于 2010-11-30T15:49:13.030 回答