Capitalizing words in a string using c#

大憨熊 提交于 2019-11-27 17:22:01

问题


I need to take a string, and capitalize words in it. Certain words ("in", "at", etc.), are not capitalized and are changed to lower case if encountered. The first word should always be capitalized. Last names like "McFly" are not in the current scope so the same rule will apply to them - only first letter capitalized.

For example: "of mice and men By CNN" should be changed to "Of Mice and Men by CNN". (Therefore ToTitleString won't work here)

I'm wondering what would be the best way to do that. What I thought of is to split the string by spaces, and go over each word, changing it if necessary, and concatenating it to the previous word, and so on. It seems pretty naive and I was wondering if there's a better way to do it, using .Net 3.5.


回答1:


Depending on how often you plan on doing the capitalization I'd go with the naive approach. You could possibly do it with a regular expression, but the fact that you don't want certain words capitalized makes that a little trickier.

Edit:

You can do it with two passes using regexes

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

This outputs Of Mice and Men Isn't by CNN.

The first expression capitalizes every letter on a word boundary and the second one downcases any words matching the list that are surrounded by whitespace.

The downsides to this approach is that you're using regexs (now you have two problems) and you'll need to keep that list of excluded words up to date. My regex-fu isn't good enough to be able to do it in one expression, but it might be possible.




回答2:


Use

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

to convert to proper case and then you can loop through the keywords as you have mentioned.




回答3:


Here is answer How to Capitalize names

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:


Why not use ToTitleCase() first and then keep a list of applicable words and Replace back to the all-lower-case version of those applicable words (provided that list is small).

The list of applicable words could be kept in a dictionary and looped through pretty efficiently, replacing with the .ToLower() equivalent.




回答5:


Try something like this:

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

You can then later update the CapitalizeWord method if you need to handle complex surnames. Add those methods to a class and use it like this:

SomeClass.TitleCase("a test is a sentence", "is", "a"); // returns "A Test is a Sentence"



回答6:


You can have a Dictionary having the words you would like to ignore, split the sentence in phrases (.split(' ')) and for each phrase, check if the phrase exists in the dictionary, if it does not, capitalize the first character and then, add the string to a string buffer. If the phrase you are currently processing is in the dictionary, simply add it to the string buffer.




回答7:


A slight improvement on jonnii's answer:

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:


You should create your own function like you're describing.




回答9:


A non-clever approach that handles the simple case:

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



回答10:


The easiest obvious solution (for English sentences) would be to:

  • "sentence".Split(" ") the sentence on space characters
  • Loop through each item
  • Capitalize the first letter of each item - item[i][0].ToUpper(),
  • Remerge back into a string joined on a space.
  • Repeat this process with "." and "," using that new string.


来源:https://stackoverflow.com/questions/4315564/capitalizing-words-in-a-string-using-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!