代码之家  ›  专栏  ›  技术社区  ›  KeithS

CamelCase转换为友好名称,即枚举常量;问题?

  •  5
  • KeithS  · 技术社区  · 14 年前

    this question ,我提到,我们使用大写camelcase解析来获取一个枚举常量的描述,该常量没有用description属性修饰,但它很幼稚,并且并不是在所有情况下都有效。我重温了它,我想到了:

    var result = Regex.Replace(camelCasedString, 
                                @"(?<a>(?<!^)[A-Z][a-z])", @" ${a}");
    result = Regex.Replace(result,
                                @"(?<a>[a-z])(?<b>[A-Z0-9])", @"${a} ${b}");
    

    第一个Replace查找大写字母,后跟小写字母,除非大写字母是字符串的开头(以避免返回和修剪),并添加前面的空格。它处理基本的大写标识符,并引导所有的缩写词,如FDICInsured。

    第二个Replace查找小写字母,后跟大写字母或数字,并在两者之间插入空格。这是为了处理中间或尾随首字母缩写词或标识符中的数字的特殊但常见的情况(前导数字除外,在C风格的语言中通常是禁止的)。

    运行一些基本单元测试时,这两个组合正确地分隔了以下所有标识符:NoDescription、HasLotsOfWords、AAANoDescription、thishhastheacronymabcintermiddle、MyTrailingAcronymID、number3、IDo3Things、IAmAValueWithSingleLetterWords和basic(没有添加任何空格)。

    因此,我发布这篇文章首先是为了与其他可能觉得有用的人分享,其次是问两个问题:

    1. result = Regex.Replace(result, "^[a-z]", m=>m.ToString().ToUpper());

    2. 有人能想出一个方法来表达这一点,或者说更优雅一点吗?我希望合并Replace调用,但由于它们对匹配项执行两种不同的操作,因此无法使用这两个字符串。它们可以与字符串上的RegexReplace扩展方法组合成一个方法链,但是谁能想到更好的方法呢?

    3 回复  |  直到 8 年前
        1
  •  12
  •   Philip Rieck    14 年前

    因此,虽然我同意汉斯帕桑在这里,我不得不说,我不得不尝试我的手,使一个正则表达式作为扶手椅正则表达式用户。

    (?<a>(?<!^)((?:[A-Z][a-z])|(?:(?<!^[A-Z]+)[A-Z0-9]+(?:(?=[A-Z][a-z])|$))|(?:[0-9]+)))
    

    是我想到的。它似乎通过了你在问题中提出的所有考验。

    所以呢

    var result = Regex.Replace(camelCasedString, @"(?<a>(?<!^)((?:[A-Z][a-z])|(?:(?<!^[A-Z]+)[A-Z0-9]+(?:(?=[A-Z][a-z])|$))|(?:[0-9]+)))", @" ${a}");
    

        2
  •  1
  •   atk    14 年前

    这并不是直接回答问题,而是为什么不采用标准的C#API并将每个类转换成友好的名称来进行测试呢?这需要一些手动验证,但它会给你一个很好的标准名称列表来测试。

        3
  •  0
  •   Jon Hanna    14 年前

    假设你遇到的每一个案例都适用于此(你问我们一些不适用的例子,然后给我们一些,所以你甚至没有问题了)。

    这仍然会将UI绑定到编程标识符,从而使编程和UI更改变得脆弱。

    它仍然假设您的程序将只使用一种语言。要么你的潜在市场太小,仅仅索引一组名称就足够可伸缩(例如,一个客户定制或内部项目),要么你假设你永远不会成功到需要提供给其他语言或你选择的第一语言的其他方言。

    “好吧,只要我们是个失败者就行”听起来像是平衡设计的及格分数吗?

    要么将其编码为使用资源,要么将其编码为盲目地传递枚举名称,或者使用名称数组,因为这至少在以后是可以修改的。