В своем ответе на этот вопрос я упомянул, что мы использовали синтаксический анализ 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, но кто-нибудь может подумать о лучшем?