【发布时间】:2010-09-01 19:28:57
【问题描述】:
在我对this question 的回答中,我提到我们使用UpperCamelCase 解析来获取未使用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 查找一个大写字母,后跟一个小写字母,除非大写字母是字符串的开头(以避免必须返回和修剪),并在前面添加一个空格。它处理您的基本 UpperCamelCase 标识符,以及像 FDICInsured 这样的全大写首字母缩略词。
第二个 Replace 查找后跟一个大写字母或数字的小写字母,并在两者之间插入一个空格。这是为了处理特殊但常见的中间或尾随首字母缩略词,或标识符中的数字(前导数字除外,这通常在 C 风格的语言中是被禁止的)。
运行一些基本单元测试,这两者的组合正确分隔了以下所有标识符:NoDescription、HasLotsOfWords、AAANoDescription、ThisHasTheAcronymABCInTheMiddle、MyTrailingAcronymID、TheNumber3、IDo3Things、IAmAValueWithSingleLetterWords 和 Basic(未添加任何空格) .
所以,我发布此内容首先是为了与其他可能觉得它有用的人分享,其次是问两个问题:
任何人都看到了一个遵循常见的 CamelCase-ish 约定的情况,这种情况不会以这种方式正确地分成友好的字符串?我知道它不会分隔相邻的首字母缩略词 (FDICFCUAInsured),不会对 FdicInsured 等“正确”的驼峰式首字母缩略词进行大写,或者将 lowerCamelCased 标识符的第一个字母大写(但很容易添加 -
result = Regex.Replace(result, "^[a-z]", m=>m.ToString().ToUpper());)。还有什么?谁能找到一种方法来表达这一说法,或者更优雅?我一直在寻找组合 Replace 调用,但是由于它们对匹配项做了两种不同的事情,因此这两个字符串无法完成。它们可以通过 String 上的 RegexReplace 扩展方法组合成一个方法链,但谁能想到更好的方法?
【问题讨论】:
-
pet-peeve time:“首字母缩略词”是发音像单词的缩写(雷达、北约、正则表达式)。拼写的缩写(ABC、FDIC、XML)实际上称为“首字母缩写词”。