【问题标题】:Function to Make Pascal Case? (C#)制作帕斯卡案例的功能? (C#)
【发布时间】:2010-08-02 09:48:40
【问题描述】:

我需要一个函数来接受一个字符串和“pascal case”。新单词开始的唯一指示符是下划线。以下是一些需要清理的示例字符串:

  1. price_old => 应该是 PriceOld
  2. rank_old => 应该是 RankOld

我开始研究一个使第一个字符大写的函数:

public string FirstCharacterUpper(string value)
{
 if (value == null || value.Length == 0)
  return string.Empty;
 if (value.Length == 1)
  return value.ToUpper();
 var firstChar = value.Substring(0, 1).ToUpper();
 return firstChar + value.Substring(1, value.Length - 1);
}

上述函数没有做的是删除下划线和“ToUpper”下划线右侧的字符。

此外,关于如何对没有任何指示符(如下划线)的字符串进行帕斯卡大小写的任何想法。例如:

  1. 公司来源
  2. 财务趋势
  3. 会计变更类型

这里的主要挑战是确定一个单词的结尾和另一个单词的开头。我想我需要某种查找字典来确定新词从哪里开始?我们那里已经有图书馆可以做这种事情了吗?

谢谢,

保罗

【问题讨论】:

  • 一个简短的评论 - 那是帕斯卡案例。 Camel case 以小写字母开头,例如rankOld.
  • @Jon O,很高兴知道......正在更新......
  • 另一个快速评论 - 当您想要从某个起点开始的整个子字符串时,没有必要指定长度。所以代替 value.Substring(1, value.Length - 1) 你可以简单地做 value.Substring(1).
  • @Anton 感谢您的提示,我将开始使用较短的重载。
  • 警告词:如果你沿着字典路径去识别字符串的组成部分,而没有指示每个单词的开始和结束位置,那么要非常小心,否则你可能会得到意想不到的结果——专家交流的人可能会告诉你更多关于这个问题的信息。

标签: c# regex camelcasing


【解决方案1】:

您可以使用TextInfo.ToTitleCase 方法,然后删除“_”字符。

所以,使用我拥有的扩展方法:

http://theburningmonk.com/2010/08/dotnet-tips-string-totitlecase-extension-methods

你可以这样做:

var s = "price_old";
s.ToTitleCase().Replace("_", string.Empty);

【讨论】:

  • @theburningmonk 我喜欢我目前所看到的......可能最终会使用这种方法。
  • @Paul - 没有问题 ;-) 很高兴我能帮上忙!
  • MSDN 声明此功能实现不正确,因此可能会发生变化;所以要小心 .NET 的新版本。
  • @Jan - 但是即使相关的 MSDN 文章没有明确说明,框架中的任何内容都可能会发生变化。我认为这不足以成为克制的理由从使用它们。
  • 这不适用于“iTunes”之类的东西。它产生“iTunes”而不是“iTunes”,我认为这是正确的。
【解决方案2】:

嗯,第一件事很简单:

string.Join("", "price_old".Split(new [] { '_' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Substring(0, 1).ToUpper() + s.Substring(1)).ToArray());

返回PriceOld

第二件事要困难得多。由于companysource 可能是CompanySourceCompanysOurce,可以自动化但非常错误。您将需要一个English dictionary,并猜测(嗯,我的意思是很多)哪个单词组合是正确的。

【讨论】:

  • 正如您有效指出的那样,处理文字很困难。我想没有办法解决它,我将不得不进行某种字典查找。我想我希望有人已经开发了我可以使用的东西。
  • +1:用于指出第二件事的字典解决方案
【解决方案3】:

试试这个:

public static string GetPascalCase(string name)
{
    return Regex.Replace(name, @"^\w|_\w", 
        (match) => match.Value.Replace("_", "").ToUpper());
}

Console.WriteLine(GetPascalCase("price_old")); // => Should be PriceOld
Console.WriteLine(GetPascalCase("rank_old" )); // => Should be RankOld

【讨论】:

  • 只有这比拆分和子串慢四倍,编译正则表达式时慢两倍(这样做 100.000 次)。
【解决方案4】:

带下划线:

s = Regex.Replace(s, @"(?:^|_)([a-z])",
      m => m.Groups[1].Value.ToUpper());

没有下划线:

你自己在那里。但是继续搜索;如果没有人以前这样做过,我会感到惊讶。

【讨论】:

  • 正是我想要的,所以 +1。添加一些有关此正则表达式如何工作的信息将使答案更加有价值。对于那些希望它运行得更快的人,您可以将其与选项一起使用并使正则表达式预编译:s = Regex.Replace(s, @"(?:^|_)([a-z])", m => m.Groups[1].Value.ToUpper(), RegexOptions.Compiled);
【解决方案5】:

对于拆分连接单词的第二个问题,您可以使用我们最好的朋友 Google & Co。如果您的连接输入由常用的英文单词组成,则搜索引擎将单个单词作为替代搜索的命中率很高查询

如果您输入示例输入,Google 和 Bing 会建议以下内容:

original             | Google                | Bing
=====================================================================
companysource        | company source        | company source 
financialtrend       | financial trend       | financial trend
accountingchangetype | accounting changetype | accounting change type

this exaple

为此编写一个小屏幕刮板应该相当容易。

【讨论】:

【解决方案6】:

对于那些需要非正则表达式解决方案的人

 public static string RemoveAllSpaceAndConcertToPascalCase(string status)
        {
            var textInfo = new System.Globalization.CultureInfo("en-US").TextInfo;
            var titleCaseStr = textInfo.ToTitleCase(status);
            string result = titleCaseStr.Replace("_","").Replace(" ", "");

            return result;
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-27
    • 1970-01-01
    • 2019-06-28
    • 1970-01-01
    • 2022-10-21
    • 2022-06-11
    • 1970-01-01
    相关资源
    最近更新 更多