Я уже чувствую пламя, но мне нравятся регулярные выражения для такого рода вещей.
public static string UnCamelCase(string str)
{
return Regex.Replace(str, "([a-z])([A-Z])", "$1 $2");
}
(Это может быть не быстрее, чем ваша реализация, но для me это более понятно.)
И, очевидно, это было бы еще быстрее (во время выполнения)
private static Regex _unCamelRegex = new Regex("([a-z])([A-Z])", RegexOptions.Compiled);
public static string UnCamelCase(string str)
{
return _unCamelRegex.Replace(str, "$1 $2");
}
Это решит проблему, поднятую Питом Киркхэмом ниже (что касается строк в верблюжьей оболочке, таких как HTTPRequest):
private static Regex _unCamelRegex1 = new Regex("([a-z])([A-Z])", RegexOptions.Compiled);
private static Regex _unCamelRegex2 = new Regex("([A-Z]+)([A-Z])([a-z])", RegexOptions.Compiled);
public static string UnCamelCase(string str)
{
return _unCamelRegex2.Replace(_unCamelRegex1.Replace(str, "$1 $2"), "$1 $2$3");
}
Этот занимает HTTPRequestFOOBarGork
и возвращает HTTP Request FOO Bar Gork
Таким образом, я протестировал итерационный метод в сравнении с методом регулярных выражений, используя реализацию OP (с изменением 'start at 1 и skip> 0 check') и мой второй ответ (тот, который был статически скомпилирован с объектом Regex). Обратите внимание, что результаты не включают время компиляции регулярных выражений. Для 2 миллионов вызовов (используя один и тот же вход FooBarGork):
Итерация: 00: 00: 00.80
Регулярное выражение: 00: 00: 06.71
Итак, очевидно, что итерационный подход намного эффективнее . Я включил фиксированную версию реализации OP (, как предложено Джейсоном Пуньоном, любой кредит должен идти к нему), которая также учитывает нулевой или пустой аргумент:
public static string UnCamelCaseIterative(string str)
{
if (String.IsNullOrEmpty(str))
return str;
/* Note that the .ToString() is required, otherwise the char is implicitly
* converted to an integer and the wrong overloaded ctor is used */
StringBuilder sb = new StringBuilder(str[0].ToString());
for (int i = 1; i < str.Length; i++)
{
if (char.IsUpper(str, i))
sb.Append(" ");
sb.Append(str[i]);
}
return sb.ToString();
}