简体   繁体   English

如何使用 C# 将每个单词的第一个字符或整个字符串的第一个字符大写?

[英]How to capitalize the first character of each word, or the first character of a whole string, with C#?

I could write my own algorithm to do it, but I feel there should be the equivalent to ruby's humanize in C#.我可以编写自己的算法来做到这一点,但我觉得在 C# 中应该有相当于ruby 的人性化

I googled it but only found ways to humanize dates.我用谷歌搜索,但只找到了人性化日期的方法。

Examples:例子:

  • A way to turn "Lorem Lipsum Et" into "Lorem lipsum et"一种将“Lorem Lipsum Et”变成“Lorem Lipsum et”的方法
  • A way to turn "Lorem lipsum et" into "Lorem Lipsum Et"一种将“Lorem Lipsum et”变成“Lorem Lipsum Et”的方法

As discussed in the comments of @miguel's answer , you can use TextInfo.ToTitleCase which has been available since .NET 1.1.正如@miguel 的回答的评论中所讨论,您可以使用自 .NET 1.1 起可用的TextInfo.ToTitleCase Here is some code corresponding to your example:以下是与您的示例相对应的一些代码:

string lipsum1 = "Lorem lipsum et";

// Creates a TextInfo based on the "en-US" culture.
TextInfo textInfo = new CultureInfo("en-US",false).TextInfo;

// Changes a string to titlecase.
Console.WriteLine("\"{0}\" to titlecase: {1}", 
                  lipsum1, 
                  textInfo.ToTitleCase( lipsum1 )); 

// Will output: "Lorem lipsum et" to titlecase: Lorem Lipsum Et

It will ignore casing things that are all caps such as "LOREM LIPSUM ET" because it is taking care of cases if acronyms are in text so that "IEEE" (Institute of Electrical and Electronics Engineers) won't become "ieee" or "Ieee".它将忽略所有大写的大小写,例如“LOREM LIPSUM ET”,因为它会处理文本中的首字母缩略词,以便“IEEE”(电气和电子工程师协会)不会成为“ieee”或“伊”。

However if you only want to capitalize the first character you can do the solution that is over here … or you could just split the string and capitalize the first one in the list:但是,如果您只想大写第一个字符,您可以执行此处的解决方案……或者您可以拆分字符串并大写列表中的第一个字符:

string lipsum2 = "Lorem Lipsum Et";

string lipsum2lower = textInfo.ToLower(lipsum2);

string[] lipsum2split = lipsum2lower.Split(' ');

bool first = true;

foreach (string s in lipsum2split)
{
    if (first)
    {
        Console.Write("{0} ", textInfo.ToTitleCase(s));
        first = false;
    }
    else
    {
        Console.Write("{0} ", s);
    }
}

// Will output: Lorem lipsum et 

Use regular expressions for this looks much cleaner:使用正则表达式看起来更干净:

string s = "the quick brown fox jumps over the lazy dog";
s = Regex.Replace(s, @"(^\w)|(\s\w)", m => m.Value.ToUpper());

There is another elegant solution :还有另一个优雅的解决方案:

Define the function ToTitleCase in an static class of your projet在项目的静态类中定义函数ToTitleCase

using System.Globalization;

public static string ToTitleCase(this string title)
{
    return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(title.ToLower()); 
}

And then use it like a string extension anywhere on your project:然后在项目的任何地方使用它作为字符串扩展:

"have a good day !".ToTitleCase() // "Have A Good Day !"

All the examples seem to make the other characters lowered first which isn't what I needed.所有的例子似乎首先降低了其他字符,这不是我需要的。

customerName = CustomerName <-- Which is what I wanted customerName = CustomerName <-- 这就是我想要的

this is an example = This Is An Example this is an example = This Is An Example

public static string ToUpperEveryWord(this string s)
{
    // Check for empty string.  
    if (string.IsNullOrEmpty(s))
    {
        return string.Empty;
    }

    var words = s.Split(' ');

    var t = "";
    foreach (var word in words)
    {
        t += char.ToUpper(word[0]) + word.Substring(1) + ' ';
    }
    return t.Trim();
}

If you just want to capitalize the first character, just stick this in a utility method of your own:如果您只想将第一个字符大写,只需将其粘贴到您自己的实用方法中即可:

return string.IsNullOrEmpty(str) 
    ? str
    : str[0].ToUpperInvariant() + str.Substring(1).ToLowerInvariant();

There's also a library method to capitalize the first character of every word:还有一个库方法可以将每个单词的第一个字符大写:

http://msdn.microsoft.com/en-us/library/system.globalization.textinfo.totitlecase.aspx http://msdn.microsoft.com/en-us/library/system.globalization.textinfo.totitlecase.aspx

CSS technique is ok but only changes the presentation of the string in the browser. CSS 技术还可以,但只会改变字符串在浏览器中的呈现方式。 A better method is to make the text itself capitalised before sending to browser.更好的方法是在发送到浏览器之前使文本本身大写。

Most of the above implimentations are ok, but none of them address the issue of what happens if you have mixed case words that need to be preserved, or if you want to use true Title Case, for example:上面的大多数实现都可以,但它们都没有解决如果您有需要保留的混合大小写单词,或者如果您想使用真正的标题案例会发生什么的问题,例如:

"Where to Study PHd Courses in the USA" “在美国哪里学习博士课程”

or要么

"IRS Form UB40a" “国税局表格 UB40a”

Also using CultureInfo.CurrentCulture.TextInfo.ToTitleCase(string) preserves upper case words as in "sports and MLB baseball" which becomes "Sports And MLB Baseball" but if the whole string is put in upper case, then this causes an issue.同样使用 CultureInfo.CurrentCulture.TextInfo.ToTitleCase(string) 会保留大写单词,如“sports and MLB 棒球”中的“体育和 MLB 棒球”,但如果整个字符串都为大写,则会导致问题。

So I put together a simple function that allows you to keep the capital and mixed case words and make small words lower case (if they are not at the start and end of the phrase) by including them in a specialCases and lowerCases string arrays:所以我组合了一个简单的函数,通过将它们包含在 specialCases 和 lowerCases 字符串数组中,允许您保留大写和混合大小写单词并使小单词小写(如果它们不在短语的开头和结尾):

public static string TitleCase(string value) {
        string titleString = ""; // destination string, this will be returned by function
        if (!String.IsNullOrEmpty(value)) {
            string[] lowerCases = new string[12] { "of", "the", "in", "a", "an", "to", "and", "at", "from", "by", "on", "or"}; // list of lower case words that should only be capitalised at start and end of title
            string[] specialCases = new string[7] { "UK", "USA", "IRS", "UCLA", "PHd", "UB40a", "MSc" }; // list of words that need capitalisation preserved at any point in title
            string[] words = value.ToLower().Split(' ');
            bool wordAdded = false; // flag to confirm whether this word appears in special case list
            int counter = 1;
            foreach (string s in words) {

                // check if word appears in lower case list
                foreach (string lcWord in lowerCases) {
                    if (s.ToLower() == lcWord) {
                        // if lower case word is the first or last word of the title then it still needs capital so skip this bit.
                        if (counter == 0 || counter == words.Length) { break; };
                        titleString += lcWord;
                        wordAdded = true;
                        break;
                    }
                }

                // check if word appears in special case list
                foreach (string scWord in specialCases) {
                    if (s.ToUpper() == scWord.ToUpper()) {
                        titleString += scWord;
                        wordAdded = true;
                        break;
                    }
                }

                if (!wordAdded) { // word does not appear in special cases or lower cases, so capitalise first letter and add to destination string
                    titleString += char.ToUpper(s[0]) + s.Substring(1).ToLower();
                }
                wordAdded = false;

                if (counter < words.Length) {
                    titleString += " "; //dont forget to add spaces back in again!
                }
                counter++;
            }
        }
        return titleString;
    }

This is just a quick and simple method - and can probably be improved a bit if you want to spend more time on it.这只是一种快速而简单的方法 - 如果您想花更多时间在上面,可能会有所改进。

if you want to keep the capitalisation of smaller words like "a" and "of" then just remove them from the special cases string array.如果您想保留诸如“a”和“of”之类的较小单词的大写,则只需将它们从特殊情况字符串数组中删除即可。 Different organisations have different rules on capitalisation.不同的组织对资本化有不同的规定。

You can see an example of this code in action on this site: Egg Donation London - this site automatically creates breadcrumb trails at the top of the pages by parsing the url eg "/services/uk-egg-bank/introduction" - then each folder name in the trail has hyphens replaced with spaces and capitalises the folder name, so uk-egg-bank becomes UK Egg Bank.您可以在此站点上看到此代码的示例: Egg Donation London - 该站点通过解析 url 例如“/services/uk-egg-bank/introduction”自动在页面顶部创建面包屑路径 - 然后每个路径中的文件夹名称将连字符替换为空格并将文件夹名称大写,因此 uk-egg-bank 成为 UK Egg Bank。 (preserving the upper case 'UK') (保留大写的“UK”)

An extension of this code could be to have a lookup table of acronyms and uppercase/lowercase words in a shared text file, database table or web service so that the list of mixed case words can be maintained from one single place and apply to many different applications that rely on the function.此代码的扩展可能是在共享文本文件、数据库表或 Web 服务中具有首字母缩略词和大写/小写单词的查找表,以便可以从一个位置维护混合大小写单词列表并应用于许多不同的依赖于该功能的应用程序。

I have achieved the same using custom extension methods.我使用自定义扩展方法实现了相同的目标。 For First Letter of First sub-string use the method yourString.ToFirstLetterUpper() .对于第一个子字符串的首字母,请使用yourString.ToFirstLetterUpper()方法。 For First Letter of Every sub-string excluding articles and some propositions , use the method yourString.ToAllFirstLetterInUpper() .对于不包括文章和一些命题的每个子字符串的首字母,请使用yourString.ToAllFirstLetterInUpper()方法。 Below is a console program:下面是一个控制台程序:

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("this is my string".ToAllFirstLetterInUpper());
            Console.WriteLine("uniVersity of lonDon".ToAllFirstLetterInUpper());
        }
    }

    public static class StringExtension
    {
        public static string ToAllFirstLetterInUpper(this string str)
        {
            var array = str.Split(" ");

            for (int i = 0; i < array.Length; i++)
            {
                if (array[i] == "" || array[i] == " " || listOfArticles_Prepositions().Contains(array[i])) continue;
                array[i] = array[i].ToFirstLetterUpper();
            }
            return string.Join(" ", array);
        }

        private static string ToFirstLetterUpper(this string str)
        {
            return str?.First().ToString().ToUpper() + str?.Substring(1).ToLower();
        }

        private static string[] listOfArticles_Prepositions()
        {
            return new[]
            {
                "in","on","to","of","and","or","for","a","an","is"
            };
        }
    }

OUTPUT输出

This is My String
University of London
Process finished with exit code 0.

There is no prebuilt solution for proper linguistic captialization in .NET. .NET 中没有用于正确语言大写的预构建解决方案。 What kind of capitialization are you going for?你想要什么样的大写? Are you following the Chicago Manual of Style conventions?您是否遵循《芝加哥风格手册》惯例? AMA or MLA? AMA 还是 MLA? Even plain english sentence capitalization has 1000's of special exceptions for words.即使是简单的英语句子大写也有 1000 多个单词的特殊例外。 I can't speak to what ruby's humanize does, but I imagine it likely doesn't follow linguistic rules of capitalization and instead does something much simpler.我无法谈论 ruby​​ 的 humanize 做了什么,但我想它可能不遵循大写的语言规则,而是做一些更简单的事情。

Internally, we encountered this same issue and had to write a fairly large amount code just to handle proper (in our little world) casing of article titles, not even accounting for sentence capitalization.在内部,我们遇到了同样的问题,不得不编写相当多的代码来处理适当的(在我们的小世界中)文章标题的大小写,甚至不考虑句子大写。 And it indeed does get "fuzzy" :)它确实变得“模糊”:)

It really depends on what you need - why are you trying to convert the sentences to proper capitalization (and in what context)?这真的取决于你需要什么——你为什么要尝试将句子转换为正确的大写(以及在什么上下文中)?

Far as I know, there's not a way to do that without writing (or cribbing) code.据我所知,没有编写(或抄袭)代码就没有办法做到这一点。 C# nets (ha!) you upper, lower and title (what you have) cases: C# nets (ha!) 你的上限、下限和标题(你拥有的)案例:

http://support.microsoft.com/kb/312890/EN-US/ http://support.microsoft.com/kb/312890/EN-US/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM