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