驼峰转换为友好名称,即枚举常数;问题? [英] CamelCase conversion to friendly name, i.e. Enum constants; Problems?
问题描述
在我的回答这个问题,我提到我们使用UpperCamelCase解析得到不装饰的描述属性的枚举常量的描述,但它是天真的,并没有在所有情况下工作。我重新审视它,这就是我想出了:
VAR的结果= Regex.Replace(camelCasedString,
@(LT; A>(小于?!^)[AZ] [AZ]),@$ {A});
结果= Regex.Replace(因此,
@(LT; A> [AZ])(LT; B> [A-Z0-9]),@$ {一} $ {b});
第一个替换寻找一个大写字母,后跟一个小写字母,除非大写字母字符串的开始(以避免必须回去和修剪),并增加了前面的空间。它处理你的基本UpperCamelCase标识符和领导全上缩写样FDICInsured。
第二替换查找一个小写字母后跟一个大写字母或数字,并插入在两者之间的空间中。这是处理中间或结尾的缩写,或数字特殊,但常见的情况在标识符(除领先的数字,这通常是禁止C风格的语言反正)。
运行一些基本的单元测试,这两者的结合正确分离以下所有标识符:NoDescription,HasLotsOfWords,AAANoDescription,ThisHasTheAcronymABCInTheMiddle,MyTrailingAcronymID,TheNumber3,IDo3Things,IAmAValueWithSingleLetterWords,和基本的(它没有任何空格添加)。
所以,我张贴这首先要与他人分享谁可能会发现它很有用,二来问两个问题:
-
任何人看到,会遵循共同的驼峰杂交约定的情况下,就不能正确地分隔成一个友好的字符串这种方式?我知道这将不相邻的缩写(FDICFCUAInsured)分离,资产重组正确的缩略语驼峰一样FdicInsured,或大写lowerCamelCased标识符的第一个字母(但一个人的轻松添加 -
结果= Regex.Replace (因此,^ [az]这样,M =方式> m.ToString()ToUpper的());
)。还有别的吗? -
任何人都可以看到一种方法,使这一个说法,或者更优雅?我一直在寻找结合替换电话,但他们做两件不同的事情他们的比赛不能与这两个字符串来完成。它们可以组合成与字符串一个REGEXREPLACE扩展方法的方法链,但任何人都可以想到的更好呢?
因此,虽然我与Hans帕桑特这里同意,我不得不说,我不得不尝试我的手在做只有在一个正则表达式作为一个扶手椅正则表达式的用户。
(小于A>(小于^)((:[AZ] [AZ])|(?:?!?!(小于^ [ AZ] +)[A-Z0-9] +(:(= [AZ] [AZ]?)| $))|(?:[0-9] +)))
是我想出了。这似乎传递你提出问题的测试。
所以
VAR的结果= Regex.Replace(camelCasedString,@(小于A>(小于^)((:[AZ] [AZ])|(?:?!?!(小于^ [ AZ] +)[A-Z0-9] +(:(= [AZ] [AZ]?)| $))|(?:[0-9] +))),@$ {A} );
它是否在一通。
In my answer to this question, I mentioned that we used UpperCamelCase parsing to get a description of an enum constant not decorated with a Description attribute, but it was naive, and it didn't work in all cases. I revisited it, and this is what I came up with:
var result = Regex.Replace(camelCasedString,
@"(?<a>(?<!^)[A-Z][a-z])", @" ${a}");
result = Regex.Replace(result,
@"(?<a>[a-z])(?<b>[A-Z0-9])", @"${a} ${b}");
The first Replace looks for an uppercase letter, followed by a lowercase letter, EXCEPT where the uppercase letter is the start of the string (to avoid having to go back and trim), and adds a preceding space. It handles your basic UpperCamelCase identifiers, and leading all-upper acronyms like FDICInsured.
The second Replace looks for a lowercase letter followed by an uppercase letter or a number, and inserts a space between the two. This is to handle special but common cases of middle or trailing acronyms, or numbers in an identifier (except leading numbers, which are usually prohibited in C-style languages anyway).
Running some basic unit tests, the combination of these two correctly separated all of the following identifiers: NoDescription, HasLotsOfWords, AAANoDescription, ThisHasTheAcronymABCInTheMiddle, MyTrailingAcronymID, TheNumber3, IDo3Things, IAmAValueWithSingleLetterWords, and Basic (which didn't have any spaces added).
So, I'm posting this first to share it with others who may find it useful, and second to ask two questions:
Anyone see a case that would follow common CamelCase-ish conventions, that WOULDN'T be correctly separated into a friendly string this way? I know it won't separate adjacent acronyms (FDICFCUAInsured), recapitalize "properly" camelCased acronyms like FdicInsured, or capitalize the first letter of a lowerCamelCased identifier (but that one's easy to add -
result = Regex.Replace(result, "^[a-z]", m=>m.ToString().ToUpper());
). Anything else?Can anyone see a way to make this one statement, or more elegant? I was looking to combine the Replace calls, but as they do two different things to their matches it can't be done with these two strings. They could be combined into a method chain with a RegexReplace extension method on String, but can anyone think of better?
So while I agree with Hans Passant here, I have to say that I had to try my hand at making it one regex as an armchair regex user.
(?<a>(?<!^)((?:[A-Z][a-z])|(?:(?<!^[A-Z]+)[A-Z0-9]+(?:(?=[A-Z][a-z])|$))|(?:[0-9]+)))
Is what I came up with. It seems to pass all the tests you put forward in the question.
So
var result = Regex.Replace(camelCasedString, @"(?<a>(?<!^)((?:[A-Z][a-z])|(?:(?<!^[A-Z]+)[A-Z0-9]+(?:(?=[A-Z][a-z])|$))|(?:[0-9]+)))", @" ${a}");
Does it in one pass.
这篇关于驼峰转换为友好名称,即枚举常数;问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!