Преобразование CamelCase в понятное имя, то есть константы Enum; Проблемы?
В моем ответеэтот вопросЯ упоминал, что мы использовали синтаксический анализ 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}");
Первая замена заменяет заглавную букву, за которой следует строчная буква, ЗА ИСКЛЮЧЕНИЕМ, где заглавная буква является началом строки (чтобы избежать необходимости возвращаться и обрезать), и добавляет предшествующий пробел. Он обрабатывает ваши базовые идентификаторы UpperCamelCase и ведущие акронимы всех верхних, как FDICInsured.
Второе «Заменить» ищет строчную букву, за которой следует заглавная буква или цифру, и вставляет пробел между ними. Это предназначено для обработки особых, но распространенных случаев средних или конечных аббревиатур или чисел в идентификаторе (кроме начальных чисел, которые в любом случае обычно запрещены в языках стиля C).
При выполнении некоторых базовых модульных тестов комбинация этих двух правильно разделила все следующие идентификаторы: NoDescription, HasLotsOfWords, AAANoDescription, ThisHasTheAcronymABCInTheMiddle, MyTrailingAcronymID, TheNumber3, IDo3Things, IAmAValueWithSingleLetterWords и не добавили ни одного (у которых не было никаких).
Итак, сначала я публикую это, чтобы поделиться им с другими, кто может найти это полезным, а затем задать два вопроса:
Кто-нибудь видел случай, который следовал бы общепринятым соглашениям CamelCase-ish, что НЕ БУДЕТ правильно разделен на дружественную строку таким образом? Я знаю, что он не будет разделять соседние аббревиатуры (FDICFCUAInsured), рекапитализировать «должным образом» акронимы в CamelCase, такие как FdicInsured, или использовать заглавные буквы первой буквы идентификатора lowerCamelCased (но это легко добавить -result = Regex.Replace(result, "^[a-z]", m=>m.ToString().ToUpper());
). Что-нибудь еще?
Может кто-нибудь увидеть способ сделать это одно заявление, или более элегантный? Я искал, чтобы объединить вызовы Replace, но так как они делают две разные вещи для своих совпадений, это не может быть сделано с этими двумя строками. Их можно объединить в цепочку методов с методом расширения RegexReplace в String, но может кто-нибудь придумать лучше?