Преобразование CamelCase в понятное имя, то есть константы Enum; Проблемы? - PullRequest
5 голосов
/ 01 сентября 2010

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

Итак, сначала я публикую это, чтобы поделиться им с другими, кто может найти это полезным, а затем задать два вопроса:

  1. Кто-нибудь видел случай, который следовал бы общепринятым соглашениям CamelCase-ish, что НЕ БУДЕТ правильно разделен на дружественную строку таким образом? Я знаю, что он не будет разделять соседние аббревиатуры (FDICFCUAInsured), рекапитализировать «должным образом» акронимы CamelCase, такие как FdicInsured, или использовать заглавные буквы первой буквы идентификатора lowerCamelCased (но это легко добавить - result = Regex.Replace(result, "^[a-z]", m=>m.ToString().ToUpper());). Что-нибудь еще?

  2. Может кто-нибудь увидеть способ сделать это одно утверждение, или более элегантный? Я искал, чтобы объединить вызовы Replace, но так как они делают две разные вещи для своих совпадений, это не может быть сделано с этими двумя строками. Их можно объединить в цепочку методов с методом расширения RegexReplace в String, но кто-нибудь может подумать о лучшем?

Ответы [ 3 ]

12 голосов
/ 02 сентября 2010

Итак, хотя я согласен с Хансом Пассантом здесь, я должен сказать, что мне пришлось попробовать свои силы, чтобы сделать его одним регулярным выражением в качестве пользователя регулярного выражения в кресле.

(?<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 голос
/ 01 сентября 2010

не то чтобы это прямо отвечало на вопрос, но почему бы не протестировать, взяв стандартный C # API и преобразовав каждый класс в понятное имя? Требуется ручная проверка, но вы получите хороший список стандартных имен для проверки.

0 голосов
/ 02 сентября 2010

Допустим, каждый случай, с которым вы сталкиваетесь, работает с этим (вы спрашиваете нас о примерах, которые не будут, а затем даете нам некоторые, так что у вас даже не осталось вопроса).

Этопо-прежнему связывает пользовательский интерфейс с программными идентификаторами таким образом, что это делает программирование и изменения пользовательского интерфейса хрупкими.

При этом предполагается, что ваша программа будет использоваться только на одном языке.Либо ваш потенциальный рынок настолько мал, что просто индексирование массива имен будет достаточно масштабируемым (например, индивидуальный заказ или собственный проект), либо вы предполагаете, что никогда не будете достаточно успешны, чтобы быть доступными для других языков.или другие диалекты вашего первого выбранного языка.

«Хорошо, это будет работать до тех пор, пока мы провалимся», звучит как проходной балл в балансирующем дизайне?использовать ресурсы или кодировать его, чтобы передать имя перечисления вслепую или использовать массив имен, так как это, по крайней мере, впоследствии может быть изменено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...