【问题标题】:Adding space between a string (eg. HelloWord -> Hello World) [duplicate]在字符串之间添加空格(例如,HelloWord -> Hello World)[重复]
【发布时间】:2015-07-07 08:51:05
【问题描述】:

假设我有几个字符串:CustomerName、CustomerID、ContactNumber,...如何将这些字符串转换为 Customer Name、Customer ID、Contact Number?是否有任何内置方法可用于在 c# 中实现这一目标?还是我一个一个手动做?

【问题讨论】:

  • 正则表达式? Regex.Replace(>, @"([a-z])([A-Z])", "$1 $2")
  • 我可能会使用属性,比如DescriptionAttribute(使用内置属性)或者更好的是,实现FriendlyName(string name) 属性来应用。这意味着不必完全实施您的建议。

标签: c# string whitespace


【解决方案1】:

除了基于正则表达式的方法(参见解决方案 2)之外,您想要实现的目标没有内置方法。


解决方案 1(无正则表达式,自定义方法):

static string SeparateTitleCases(this string source, string separator = " ")
{
    var result = new StringBuilder();
    char previousChar = default(char);

    for (int i = 0; i < source.Length; i++)
    {
        char currentChar = source[i];

        if (char.IsLower(previousChar) && // Previous char is lowercase
            char.IsUpper(currentChar)) // Current char is uppercase
        {
            result.Append(separator); // Append separator
        }
        result.Append(currentChar);

        previousChar = currentChar;
    }

    return result.ToString();
}

示例用法:

Console.WriteLine("CustomerName".SeparateTitleCases()); // Customer Name
Console.WriteLine("CustomerID".SeparateTitleCases()); // Customer ID
Console.WriteLine("CustomerName CustomerID".SeparateTitleCases()); // Customer Name Customer ID

解决方案 2(正则表达式):

string pattern = @"([^\s])([A-Z]+[a-z]*)";
string replacement = "$1 $2";            

Console.WriteLine(Regex.Replace("CustomerName", pattern, replacement)); // Customer Name
Console.WriteLine(Regex.Replace("CustomerID", pattern, replacement)); // Customer ID
Console.WriteLine(Regex.Replace("CustomerName CustomerID", pattern, replacement)); // Customer Name Customer ID

【讨论】:

  • 是的,在各种库中都有类似的实现。我认为没有理由再次实施。
【解决方案2】:

你可以使用这个扩展方法:

private static readonly HashSet<UnicodeCategory> SeparatorCharCategories = new HashSet<UnicodeCategory>{ UnicodeCategory.UppercaseLetter, UnicodeCategory.TitlecaseLetter, UnicodeCategory.DecimalDigitNumber };

public static String SeparateCharCategories(this string input, string delimiter = " ")
{
    StringBuilder sb = new StringBuilder(input.Length);
    UnicodeCategory lastCharCategory = Char.GetUnicodeCategory(input[0]);
    for(int i = 0; i < input.Length; i++)
    {
        UnicodeCategory charCategory = Char.GetUnicodeCategory(input[i]);
        if (lastCharCategory != charCategory && SeparatorCharCategories.Contains(charCategory))
            sb.Append(delimiter);
        sb.Append(input[i]);
        lastCharCategory = charCategory;
    }
    return sb.ToString();
}

您的样本和其他极端情况:

var items = new[] { "CustomerName", "CustomerID", "ContactNumber", "PurchaseOrders", "purchaseOrders", "The2Unlimited", "Unlimited2", "222Unlimited", "The222Unlimited", "Unlimited222", "ATeam", "TheATeam", "TeamA", "HTMLGuide", "TheHTMLGuide", "TheGuideToHTML", "HTMLGuide5", "TheHTML5Guide", "TheGuideToHTML5", "TheUKAllStars", "AllStarsUK", "UKAllStars" };
foreach (string str in items)
    Console.WriteLine(str.SeparateCharCategories(" "));

您看到不支持首字母缩略词,所以HTMLGuide 仍然是HTMLGuide

Customer Name
Customer ID
Contact Number
Purchase Orders
purchase Orders
The 2 Unlimited
Unlimited 2
222 Unlimited
The 222 Unlimited
Unlimited 222
ATeam
The ATeam
Team A
HTMLGuide
The HTMLGuide
The Guide To HTML
HTMLGuide 5
The HTML 5 Guide
The Guide To HTML 5
The UKAll Stars
All Stars UK
UKAll Stars

【讨论】:

  • "BuildABear""RentAHouse" 有什么期望? 补充:"CustomerIDNumber"
  • 这个方法返回Customer IDNumber,不确定OP期望什么。
  • @JeppeStigNielsen:您对"CUSTOMER" 有什么期望?肯定不是"C U S T O M E R"
  • 你明白我的(不清楚)观点。我们想要的东西并没有很好地定义。我希望"CustomerIDNumber" 变成"Customer ID Number",而"ASCIIEncoding" 变成"ASCII Encoding"。但是像"IAMan"(“我,一个男人”)这样的连续单字母单词我们无法处理,所以它会变成"IA Man",而不是"I A Man"。 (英语没有那么多单字母单词。)顺便说一句,命名ASCIIEncoding 不好。对于包含三个或更多字母的首字母缩略词,应改用 AsciiEncoding 形式。
【解决方案3】:

我假设CustomerNameCustomerID 是属性名称?您需要一些方法来反映这些名称,然后您可以使用 Humanizer Lib 添加空格。

像这样使用它:

"CustomerName".Humanize(LetterCasing.Title) => "Customer Name";

【讨论】:

    猜你喜欢
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多