将所有第一个字母转换为大写,每个单词保持小写

Posted

技术标签:

【中文标题】将所有第一个字母转换为大写,每个单词保持小写【英文标题】:Convert all first letter to upper case, rest lower for each word 【发布时间】:2010-12-28 22:25:00 【问题描述】:

我有一串文本(大约 5-6 个单词)需要转换。

目前文字如下:

THIS IS MY TEXT RIGHT NOW

我想把它转换成:

This Is My Text Right Now

我可以循环浏览我的字符串集合,但我不确定如何执行此文本修改。

【问题讨论】:

相关(不重复):Make first letter of a string upper case (with maximum performance) 【参考方案1】:
string s = "THIS IS MY TEXT RIGHT NOW";

s = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());

【讨论】:

太棒了!从来不知道。 哈哈,真的吗?那是什么地方?我喜欢 .NET,但有些 API 设计者是真正的混蛋。 请注意,虽然这种方法会按照提问者的要求做,但它是一种简单的算法,只是将每个单词大写,而不考虑它是什么类型的单词。这并不是真正的“标题大小写”,因为不同语言的标题大小写规则不同。它甚至不适合英语。例如,标题“about a boy”应该是英文的“About a Boy”,但这种方法会给出“About A Boy”。如果您想要 true 标题大小写,则必须编写自己的方法。 我不会称他们为混蛋。 “ToTitleCase”的问题在于它依赖于文化,因此它必须位于 System.Globalization 命名空间中。通过 CurrentThread 只是为了获取线程的当前文化(请注意,如果用户具有不同的区域设置,这可能会导致不同的行为!)。您也可以执行“CultureInfo.InvariantCulture.TextInfo.ToTitleCase()”,这可能会更好,因为 InvariantCulture 在所有文化中的行为都相同。出于兴趣 George:您会将特定于文化的字符串函数放在哪里? 还要注意关于所有大写字符串的 cmets:msdn.microsoft.com/en-us/library/…【参考方案2】:

我可能更喜欢从 CultureInfo (System.Globalization) 调用 ToTitleCase 而不是 Thread.CurrentThread ( System.Threading):

string s = "THIS IS MY TEXT RIGHT NOW";
s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());

但应该和jspcal's solution一样。

编辑

实际上,那些解决方案不一样CurrentThread --calls--> CultureInfo!


System.Threading.Thread.CurrentThread.CurrentCulture

string s = "THIS IS MY TEXT RIGHT NOW";
s = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());

IL_0000:  ldstr       "THIS IS MY TEXT RIGHT NOW"
IL_0005:  stloc.0     // s
IL_0006:  call        System.Threading.Thread.get_CurrentThread
IL_000B:  callvirt    System.Threading.Thread.get_CurrentCulture
IL_0010:  callvirt    System.Globalization.CultureInfo.get_TextInfo
IL_0015:  ldloc.0     // s
IL_0016:  callvirt    System.String.ToLower
IL_001B:  callvirt    System.Globalization.TextInfo.ToTitleCase
IL_0020:  stloc.0     // s

System.Globalization.CultureInfo.CurrentCulture

string s = "THIS IS MY TEXT RIGHT NOW";
s = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s.ToLower());

IL_0000:  ldstr       "THIS IS MY TEXT RIGHT NOW"
IL_0005:  stloc.0     // s
IL_0006:  call        System.Globalization.CultureInfo.get_CurrentCulture
IL_000B:  callvirt    System.Globalization.CultureInfo.get_TextInfo
IL_0010:  ldloc.0     // s
IL_0011:  callvirt    System.String.ToLower
IL_0016:  callvirt    System.Globalization.TextInfo.ToTitleCase
IL_001B:  stloc.0     // s

参考资料:

CultureInfo Class Thread.CurrentCulture Property

【讨论】:

【参考方案3】:

有几种方法可以将字符串的第一个字符转换为大写。

第一种方法是创建一个方法,该方法简单地将第一个字符加盖并使用子字符串附加字符串的其余部分:

public string UppercaseFirst(string s)

    return char.ToUpper(s[0]) + s.Substring(1);

第二种方式(速度稍快一些)是将字符串拆分成字符数组,然后重建字符串:

public string UppercaseFirst(string s)

    char[] a = s.ToCharArray();
    a[0] = char.ToUpper(a[0]);
    return new string(a);

【讨论】:

这个解决方案不能完全回答这个问题。问题的标题是“将所有首字母转换为大写,每个单词都小写”。但是,此解决方案仅将整个字符串的第一个字母大写。因此,此解决方案会将“hello world”转换为“Hello world”,而不是“Hello World”。 这很好。如果您使用类似 string[] words = s.Split(' '); 之类的东西,则可以完成此解决方案然后在foreach(单词中的单词)循环中调用上述方法,重构字符串......其他解决方案似乎更优雅。【参考方案4】:

如果你在网页上使用,你也可以使用 CSS:

style="text-transform:capitalize;"

【讨论】:

为什么选择 CSS?当问题要求 c# asp.net regex 标签 ASP.NET 显示 OP 正在 WEB 上执行此操作。当然,这不是问题的答案,因为 OP 需要 C# 中的解决方案,但它解决了问题并且可以作为替代解决方案。 +1【参考方案5】:

未经测试,但这样的东西应该可以工作:

var phrase = "THIS IS MY TEXT RIGHT NOW";
var rx = new System.Text.RegularExpressions.Regex(@"(?<=\w)\w");
var newString = rx.Replace(phrase,new MatchEvaluator(m=>m.Value.ToLowerInvariant()));

基本上它说“对所有出现在另一个字母数字字符后面的字母数字字符进行正则表达式匹配,然后将其替换为自身的小写版本”

【讨论】:

这个也让所有大写的单词都以大写开头,以小写继续。正是我想要的。 你有时间test it吗?【参考方案6】:

在构建大表时,速度是一个问题,所以Jamie Dixon's 第二个函数是最好的,但它并不能完全按原样工作......

它无法将所有字母都小写,它只大写字符串的第一个字母,而不是字符串中每个单词的第一个字母...以下选项解决了这两个问题:

    public string UppercaseFirstEach(string s)
    
        char[] a = s.ToLower().ToCharArray();

        for (int i = 0; i < a.Count(); i++ )
        
            a[i] = i == 0 || a[i-1] == ' ' ? char.ToUpper(a[i]) : a[i];

        

        return new string(a);
    

虽然在这一点上,这是否仍然是最快的选择是不确定的。 Regex 提供的by George Mauer 解决方案可能会更快... 足够关心的人应该测试它。

【讨论】:

它有效,但我将这个“a.Count()”更改为 a.Length【参考方案7】:

我不知道下面的解决方案是否比jspcal's answer 更有效,但我很确定它需要的对象创建少于Jamie's 和George's。

string s = "THIS IS MY TEXT RIGHT NOW";
StringBuilder sb = new StringBuilder(s.Length);
bool capitalize = true;
foreach (char c in s) 
    sb.Append(capitalize ? Char.ToUpper(c) : Char.ToLower(c));
    capitalize = !Char.IsLetter(c);

return sb.ToString();

【讨论】:

如果我们关心对象的创建,为什么不使用 for 循环在 s 上进行索引而不是使用 StringBuilder?【参考方案8】:

试试这个技巧;它返回所需的结果

CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());

别忘了使用 System.Globalization

【讨论】:

“使用 System.Globalization”是什么意思?你能详细说明一下吗? @PeterMortensen 据我记得,我认为您只需在 C# 文件的开头键入 using System.Globalization;【参考方案9】:

除了第一个答案,记得把string selectionstart index改成单词的结尾,否则你会得到字符串中字母的倒序。

s.SelectionStart = s.Length;

【讨论】:

【参考方案10】:

这是您可能感兴趣的可能解决方案之一。在一个循环中从右到左遍历一组字符,反之亦然。

public static string WordsToCapitalLetter(string value)

    if (string.IsNullOrWhiteSpace(value))
    
        throw new ArgumentException("value");
    

    int inputValueCharLength = value.Length;
    var valueAsCharArray = value.ToCharArray();

    int min = 0;
    int max = inputValueCharLength - 1;

    while (max > min)
    
        char left = value[min];
        char previousLeft = (min == 0) ? left : value[min - 1];

        char right = value[max];
        char nextRight = (max == inputValueCharLength - 1) ? right : value[max - 1];

        if (char.IsLetter(left) && !char.IsUpper(left) && char.IsWhiteSpace(previousLeft))
        
            valueAsCharArray[min] = char.ToUpper(left);
        

        if (char.IsLetter(right) && !char.IsUpper(right) && char.IsWhiteSpace(nextRight))
        
            valueAsCharArray[max] = char.ToUpper(right);
        

        min++;
        max--;
    

    return new string(valueAsCharArray);

【讨论】:

【参考方案11】:

jspcal's answer 作为字符串扩展名。

文件 Program.cs

class Program

    static void Main(string[] args)
    
        var myText = "MYTEXT";
        Console.WriteLine(myText.ToTitleCase()); //Mytext
    

文件 StringExtensions.cs

using System;
public static class StringExtensions


    public static string ToTitleCase(this string str)
    
        if (str == null)
            return null;

        return System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
    

【讨论】:

以上是关于将所有第一个字母转换为大写,每个单词保持小写的主要内容,如果未能解决你的问题,请参考以下文章

字符操作

我看书JavaScript将每个单词首字母变大写

JavaScript将字符串中的每一个单词的第一个字母变为大写其余均为小写

如何使用ruby / rails将所有大写字母转换为适当的首字母大写字母,其余为小写?

sed one-liner将全部大写转换为小写?

CSS---文本相关属性