将字符串转换为标题格式

357

我有一个包含大小写混合单词的字符串。

例如:string myData = "a Simple string";

我需要将每个单词(由空格分隔)的第一个字符转换为大写。因此,我希望结果为:string myData ="A Simple String";

有没有简单的方法来做到这一点?我不想拆分字符串并进行转换(那将是我的最后手段)。此外,保证字符串是英文。


1
http://support.microsoft.com/kb/312890 - 如何使用Visual C#将字符串转换为小写、大写或标题(proper)大小写 - ttarchala
24个回答

645

MSDN: TextInfo.ToTitleCase

确保你包含了:using System.Globalization

string title = "war and peace";

TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;

title = textInfo.ToTitleCase(title); 
Console.WriteLine(title) ; //War And Peace

//When text is ALL UPPERCASE...
title = "WAR AND PEACE" ;

title = textInfo.ToTitleCase(title); 
Console.WriteLine(title) ; //WAR AND PEACE

//You need to call ToLower to make it work
title = textInfo.ToTitleCase(title.ToLower()); 
Console.WriteLine(title) ; //War And Peace

42
可以的。此外,如果一个单词全部大写,它就不能正常工作。例如:"an FBI agent shot my DOG"应翻译为"An FBI Agent Shot My DOG"。而且它无法处理"McDonalds"等词语。 - Kobi
5
@Kirschstein,这个函数确实将这些词转换为标题大小写,尽管它们不应该是英文。请查看文档:实际结果:"战争与和平" - Kobi
5
@simbolo - 我在评论中确实提到了它...你可以使用类似text = Regex.Replace(text, @"(?<!\S)\p{Ll}", m => m.Value.ToUpper());的东西,但是它还远远不够完美。例如,它仍然无法处理引号或括号 - "(one two three)" -> "(one Two Three)"。如果你想要处理这些情况,你可能需要在弄清楚具体想要做什么之后提一个新问题。 - Kobi
19
有些原因导致当我的字符串是"DR"时,如果在调用ToTitleCase()之前不先调用ToLower(),它就不会变成"Dr"...所以这是需要注意的事情... - Tod Thomson
18
如果输入文本为大写字母,则需要使用.ToLower()将其转换为小写。 - GeekzSG
显示剩余12条评论

151

试试这个:

string myText = "a Simple string";

string asTitleCase =
    System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.
    ToTitleCase(myText.ToLower());

正如已经指出的那样,使用TextInfo.ToTitleCase可能无法给你想要的精确结果。如果你需要更多控制输出的方式,你可以这样做:

IEnumerable<char> CharsToTitleCase(string s)
{
    bool newWord = true;
    foreach(char c in s)
    {
        if(newWord) { yield return Char.ToUpper(c); newWord = false; }
        else yield return Char.ToLower(c);
        if(c==' ') newWord = true;
    }
}

然后像这样使用它:

var asTitleCase = new string( CharsToTitleCase(myText).ToArray() );

1
我尝试了几种TextInfo对象的变化 - 没有错误,但原始字符串(大写)从未更新。使用了这种方法,非常感激。 - justSteve
7
根据MSDN (http://msdn.microsoft.com/en-us/library/system.globalization.textinfo.totitlecase%28v=vs.110%29.aspx)的说明: "然而,此方法目前无法正确地将全大写的单词转换为正确的大小写形式,例如缩写词" - 您应该先使用ToLower()方法(虽然这很旧,但以防其他人偶然发现并想知道原因!)。 - nizmow
仅适用于 .NET Framework 4.7.2 <= 您的框架 <= .NET Core 2.0。 - Paul Gorbas

91

又是一种变体。根据这里的几个提示,我将其简化为这个扩展方法,它非常适合我的目的:

public static string ToTitleCase(this string s) =>
    CultureInfo.InvariantCulture.TextInfo.ToTitleCase(s.ToLower());

9
实际上,CultureInfo.InvariantCulture.TextInfo.ToTitleCase(s.ToLower());会更适合! - GeekzSG
1
仅适用于 .NET Framework 4.7.2 <= 您的框架 <= .NET Core 2.0。 - Paul Gorbas
4
因为我们正在使用InvariantCulture进行标题大小写转换,所以应该使用s.ToLowerInvariant()而不是s.ToLower()。 - Vinigas

28

个人尝试了TextInfo.ToTitleCase方法,但是不理解为什么当所有字符都大写时它不起作用。

虽然我喜欢Winston Smith提供的实用函数,但让我提供我目前正在使用的函数:

public static String TitleCaseString(String s)
{
    if (s == null) return s;

    String[] words = s.Split(' ');
    for (int i = 0; i < words.Length; i++)
    {
        if (words[i].Length == 0) continue;

        Char firstChar = Char.ToUpper(words[i][0]); 
        String rest = "";
        if (words[i].Length > 1)
        {
            rest = words[i].Substring(1).ToLower();
        }
        words[i] = firstChar + rest;
    }
    return String.Join(" ", words);
}

玩弄一些测试字符串:

String ts1 = "Converting string to title case in C#";
String ts2 = "C";
String ts3 = "";
String ts4 = "   ";
String ts5 = null;

Console.Out.WriteLine(String.Format("|{0}|", TitleCaseString(ts1)));
Console.Out.WriteLine(String.Format("|{0}|", TitleCaseString(ts2)));
Console.Out.WriteLine(String.Format("|{0}|", TitleCaseString(ts3)));
Console.Out.WriteLine(String.Format("|{0}|", TitleCaseString(ts4)));
Console.Out.WriteLine(String.Format("|{0}|", TitleCaseString(ts5)));

输出结果

|Converting String To Title Case In C#|
|C|
||
|   |
||

2
@harsh: 我觉得这是一个很“丑陋”的解决方案... 在我看来,你先将整个字符串转换为小写字母并没有意义。 - Luis Quijada
5
这是有意为之的,因为如果您要求将“UNICEF和慈善”转换为标题大小写格式,您不希望它被更改为Unicef。 - Casey
7
所以,你不想在整个字符串上调用ToLower()函数,而是希望自己处理每个单独的字符并调用相同的函数?这不仅是一种丑陋的解决方案,而且没有任何好处,甚至比内置函数还要更慢。 - krillgar
3
rest = words[i].Substring(1).ToLower(); - krillgar
1
不需要,Substring使用单个整数参数开始于给定的索引位置,并返回从该位置到字符串末尾的所有内容。 - krillgar
显示剩余5条评论

25

最近我找到了一个更好的解决方案。

如果你的文本中包含所有字母都是大写的情况,那么TextInfo不会将其转换为正确的大小写。我们可以通过在内部使用小写函数来解决这个问题:

public static string ConvertTo_ProperCase(string text)
{
    TextInfo myTI = new CultureInfo("en-US", false).TextInfo;
    return myTI.ToTitleCase(text.ToLower());
}

现在这将会把所有输入内容转换为 Propercase(首字母大写)。


18
public static string PropCase(string strText)
{
    return new CultureInfo("en").TextInfo.ToTitleCase(strText.ToLower());
}

3
我很喜欢你在ToTitleCase之前加了一个ToLower,这样可以应对输入文本全是大写字母的情况。 - joelc

16

首先使用ToLower(),然后在结果上使用CultureInfo.CurrentCulture.TextInfo.ToTitleCase,以获取正确的输出。

    //---------------------------------------------------------------
    // Get title case of a string (every word with leading upper case,
    //                             the rest is lower case)
    //    i.e: ABCD EFG -> Abcd Efg,
    //         john doe -> John Doe,
    //         miXEd CaSING - > Mixed Casing
    //---------------------------------------------------------------
    public static string ToTitleCase(string str)
    {
        return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
    }

7
如果有人对紧凑框架的解决方案感兴趣:
return String.Join(" ", thestring.Split(' ').Select(i => i.Substring(0, 1).ToUpper() + i.Substring(1).ToLower()).ToArray());

使用字符串插值:返回 string.Join(" ", text.Split(' ') .Select(i => $"{i.Substring(0, 1).ToUpper()}{i.Substring(1).ToLower()}") .ToArray()); - Ted

6

以下是解决问题的方案...

CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
TextInfo textInfo = cultureInfo.TextInfo;
string txt = textInfo.ToTitleCase(txt);

4
我使用上述参考文献,得出完整的解决方案如下:
Use Namespace System.Globalization;
string str = "INFOA2Z means all information";

//需要得到类似"Infoa2z代表所有信息"的结果
//我们还需要将字符串转换为小写,否则它无法正常工作。

TextInfo ProperCase = new CultureInfo("en-US", false).TextInfo;

str = ProperCase.ToTitleCase(str.toLower());

使用C#在ASP.NET中将字符串转换为正确大小写


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接