C# 如何将文本转换为 Pascal 大小写?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18627112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 12:47:23  来源:igfitidea点击:

How can I convert text to Pascal case?

c#pascalcasingcase-conversion

提问by wlz

I have a variable name, say "WARD_VS_VITAL_SIGNS", and I want to convert it to Pascal case format: "WardVsVitalSigns"

我有一个变量名,比如“WARD_VS_VITAL_SIGNS”,我想将它转换为 Pascal 大小写格式:“WardVsVitalSigns”

WARD_VS_VITAL_SIGNS -> WardVsVitalSigns

How can I make this conversion?

我怎样才能进行这种转换?

采纳答案by Karl Anderson

First off, you are asking for title case and not camel-case, because in camel-case the first letter of the word is lowercase and your example shows you want the first letter to be uppercase.

首先,您要求标题大小写而不是骆驼大小写,因为在骆驼大小写中,单词的第一个字母是小写,而您的示例显示您希望第一个字母为大写。

At any rate, here is how you could achieve your desired result:

无论如何,您可以通过以下方式实现您想要的结果:

string textToChange = "WARD_VS_VITAL_SIGNS";
System.Text.StringBuilder resultBuilder = new System.Text.StringBuilder();

foreach(char c in textToChange)
{
    // Replace anything, but letters and digits, with space
    if(!Char.IsLetterOrDigit(c))
    {
        resultBuilder.Append(" ");
    }
    else 
    { 
        resultBuilder.Append(c); 
    }
}

string result = resultBuilder.ToString();

// Make result string all lowercase, because ToTitleCase does not change all uppercase correctly
result = result.ToLower();

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

result = myTI.ToTitleCase(result).Replace(" ", String.Empty);

Note: resultis now WardVsVitalSigns.

注意:result是现在WardVsVitalSigns

If you did, in fact, want camel-case, then after all of the above, just use this helper function:

如果您确实想要驼峰式大小写,那么在完成上述所有操作之后,只需使用此辅助函数:

public string LowercaseFirst(string s)
{
    if (string.IsNullOrEmpty(s))
    {
        return string.Empty;
    }

    char[] a = s.ToCharArray();
    a[0] = char.ToLower(a[0]);

    return new string(a);
}

So you could call it, like this:

所以你可以这样称呼它:

result = LowercaseFirst(result);

回答by Nilesh

You do not need regular expression for that.

您不需要正则表达式。

var yourString = "WARD_VS_VITAL_SIGNS".ToLower().Replace("_", " ");
TextInfo info = CultureInfo.CurrentCulture.TextInfo;
yourString = info.ToTitleCase(yourString).Replace(" ", string.Empty);
Console.WriteLine(yourString);

You can modify the code as you wish.

您可以根据需要修改代码。

回答by Rodrick Chapman

var xs = "WARD_VS_VITAL_SIGNS".Split('_');

var q =

    from x in xs

    let first_char = char.ToUpper(x[0]) 
    let rest_chars = new string(x.Skip(1).Select(c => char.ToLower(c)).ToArray())

    select first_char + rest_chars;

回答by Jani Hyyti?inen

Extension method for System.Stringwith .NET Core compatible code by using Systemand System.Linq.

System.String使用System和.NET Core 兼容代码的扩展方法System.Linq

Does notmodify the original string.

难道不是修改原始字符串。

.NET Fiddle for the code below

.NET Fiddle 下面的代码

using System;
using System.Linq;

public static class StringExtensions
{
    /// <summary>
    /// Converts a string to PascalCase
    /// </summary>
    /// <param name="str">String to convert</param>

    public static string ToPascalCase(this string str){

        // Replace all non-letter and non-digits with an underscore and lowercase the rest.
        string sample = string.Join("", str?.Select(c => Char.IsLetterOrDigit(c) ? c.ToString().ToLower() : "_").ToArray());

        // Split the resulting string by underscore
        // Select first character, uppercase it and concatenate with the rest of the string
        var arr = sample?
            .Split(new []{'_'}, StringSplitOptions.RemoveEmptyEntries)
            .Select(s => $"{s.Substring(0, 1).ToUpper()}{s.Substring(1)}");

        // Join the resulting collection
        sample = string.Join("", arr);

        return sample;
    }
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine("WARD_VS_VITAL_SIGNS".ToPascalCase()); // WardVsVitalSigns
        Console.WriteLine("Who am I?".ToPascalCase()); // WhoAmI
        Console.WriteLine("I ate before you got here".ToPascalCase()); // IAteBeforeYouGotHere
        Console.WriteLine("Hello|Who|Am|I?".ToPascalCase()); // HelloWhoAmI
        Console.WriteLine("Live long and prosper".ToPascalCase()); // LiveLongAndProsper
        Console.WriteLine("Lorem ipsum dolor sit amet, consectetur adipiscing elit.".ToPascalCase()); // LoremIpsumDolorSitAmetConsecteturAdipiscingElit
    }
}

回答by WhiteleyJ

Single semicolon solution:

单分号解决方案:

public static string PascalCase(this string word)
{
    return string.Join("" , word.Split('_')
                 .Select(w => w.Trim())
                 .Where(w => w.Length > 0)
                 .Select(w => w.Substring(0,1).ToUpper() + w.Substring(1).ToLower()));
}

回答by chviLadislav

Here is my quick LINQ & regexsolution to save someone's time:

这是我的快速LINQ 和正则表达式解决方案,以节省某人的时间:

using System;
using System.Linq;
using System.Text.RegularExpressions;

public string ToPascalCase(string original)
{
    Regex invalidCharsRgx = new Regex("[^_a-zA-Z0-9]");
    Regex whiteSpace = new Regex(@"(?<=\s)");
    Regex startsWithLowerCaseChar = new Regex("^[a-z]");
    Regex firstCharFollowedByUpperCasesOnly = new Regex("(?<=[A-Z])[A-Z0-9]+$");
    Regex lowerCaseNextToNumber = new Regex("(?<=[0-9])[a-z]");
    Regex upperCaseInside = new Regex("(?<=[A-Z])[A-Z]+?((?=[A-Z][a-z])|(?=[0-9]))");

    // replace white spaces with undescore, then replace all invalid chars with empty string
    var pascalCase = invalidCharsRgx.Replace(whiteSpace.Replace(original, "_"), string.Empty)
        // split by underscores
        .Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries)
        // set first letter to uppercase
        .Select(w => startsWithLowerCaseChar.Replace(w, m => m.Value.ToUpper()))
        // replace second and all following upper case letters to lower if there is no next lower (ABC -> Abc)
        .Select(w => firstCharFollowedByUpperCasesOnly.Replace(w, m => m.Value.ToLower()))
        // set upper case the first lower case following a number (Ab9cd -> Ab9Cd)
        .Select(w => lowerCaseNextToNumber.Replace(w, m => m.Value.ToUpper()))
        // lower second and next upper case letters except the last if it follows by any lower (ABcDEf -> AbcDef)
        .Select(w => upperCaseInside.Replace(w, m => m.Value.ToLower()));

    return string.Concat(pascalCase);
}

Example output:

示例输出:

"WARD_VS_VITAL_SIGNS"          "WardVsVitalSigns"
"Who am I?"                    "WhoAmI"
"I ate before you got here"    "IAteBeforeYouGotHere"
"Hello|Who|Am|I?"              "HelloWhoAmI"
"Live long and prosper"        "LiveLongAndProsper"
"Lorem ipsum dolor..."         "LoremIpsumDolor"
"CoolSP"                       "CoolSp"
"AB9CD"                        "Ab9Cd"
"CCCTrigger"                   "CccTrigger"
"CIRC"                         "Circ"
"ID_SOME"                      "IdSome"
"ID_SomeOther"                 "IdSomeOther"
"ID_SOMEOther"                 "IdSomeOther"
"CCC_SOME_2Phases"             "CccSome2Phases"
"AlreadyGoodPascalCase"        "AlreadyGoodPascalCase"
"999 999 99 9 "                "999999999"
"1 2 3 "                       "123"
"1 AB cd EFDDD 8"              "1AbCdEfddd8"
"INVALID VALUE AND _2THINGS"   "InvalidValueAnd2Things"

回答by Dr TJ

Some answers are correct but I really don't understand why they set the text to LowerCase first, because the ToTitleCasewill handle that automatically:

有些答案是正确的,但我真的不明白为什么他们首先将文本设置为小写,因为它们ToTitleCase会自动处理:

var text = "WARD_VS_VITAL_SIGNS".Replace("_", " ");

TextInfo textInfo = CultureInfo.CurrentCulture.TextInfo;
text = textInfo.ToTitleCase(text).Replace(" ", string.Empty);

Console.WriteLine(text);