在我对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查找一个大写字母,后跟一个小写字母,EXCEPT,其中大写字母是字符串的开头(以避免必须返回并修剪),并添加一个前面的空格。它处理你的基本UpperCamelCase标识符,并引导像FDICInsured这样的全高级缩略词。
第二个Replace查找小写字母后跟一个大写字母或数字,并在两者之间插入一个空格。这是为了处理特殊但常见的中间或尾随首字母缩略词或标识符中的数字(除了前导数字,通常在C风格的语言中禁止)。
运行一些基本的单元测试,这两个组合正确地分隔了以下所有标识符:NoDescription,HasLotsOfWords,AAANoDescription,ThisHasTheAcronymABCInTheMiddle,MyTrailingAcronymID,TheNumber3,IDo3Things,IAmAValueWithSingleLetterWords和Basic(没有添加任何空格)
所以,我首先发布此信息,与其他可能认为有用的人分享,然后再问两个问题:
任何人都会看到一个符合常见CamelCase-ish约定的案例,这种约定不能正确地分成友好的字符串?我知道它不会将相邻的首字母缩略词(FDICFCUAInsured)分开,重新调整“恰当”的像CamedCased的首字母缩略词,如FdicInsured,或者大写一个lowerCamelCased标识符的第一个字母(但那个很容易添加 - result = Regex.Replace(result, "^[a-z]", m=>m.ToString().ToUpper());
)。还有什么吗?
任何人都可以看到一种方法来做出这样的陈述,或者更优雅吗?我正在寻找组合替换调用,但由于他们对匹配执行两个不同的事情,因此无法使用这两个字符串完成。它们可以组合成一个方法链,在String上使用RegexReplace扩展方法,但任何人都可以想到更好吗?
答案 0 :(得分:12)
因此,虽然我同意Hans Passant的观点,但我不得不说我必须尝试将其作为扶手椅正则表达式用户的一个正则表达式。
(?<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}");
是否一次过。
答案 1 :(得分:1)
这不是直接回答问题,但为什么不通过采用标准C#API并将每个类转换为友好名称来进行测试?它需要一些手动验证,但它会为您提供一个很好的标准名称列表进行测试。
答案 2 :(得分:0)
让我们说你遇到的每一个案例都与此有关(你问我们的例子不会给我们一些,所以你甚至没有问题)。
这仍然会将UI与程序化标识符绑定在一起,使编程和UI变化都变得脆弱。
它仍假设您的程序仅使用一种语言。要么你的潜在市场如此之小,只需索引一系列名称就足够可扩展(例如,一个客户定制或内部项目),或者你假设你永远不会成功,需要可用于其他语言或您首选语言的其他方言。
“好吧,只要我们失败就能奏效”听起来像是平衡设计中的成绩?
要么使用资源进行编码,要么将其编码为盲目传递枚举名称或使用名称数组,因为之后至少可以修改。