с целями
- а) Создание функции, оптимизирующей производительность
- б) Мой собственный взгляд на CamelCase, в котором прописные аббревиатуры не были разделены (я полностью согласен, что это не стандартное определение случая верблюда или паскаля, но это не редкое использование): "TestTLAContainedCamelCase" становится "Test TLA Содержит верблюжий чемодан "(TLA = трехбуквенный аббревиатура)
Поэтому я создал следующую (не регулярную, многословную, но ориентированную на производительность) функцию
public static string ToSeparateWords(this string value)
{
if (value==null){return null;}
if(value.Length <=1){return value;}
char[] inChars = value.ToCharArray();
List<int> uCWithAnyLC = new List<int>();
int i = 0;
while (i < inChars.Length && char.IsUpper(inChars[i])) { ++i; }
for (; i < inChars.Length; i++)
{
if (char.IsUpper(inChars[i]))
{
uCWithAnyLC.Add(i);
if (++i < inChars.Length && char.IsUpper(inChars[i]))
{
while (++i < inChars.Length)
{
if (!char.IsUpper(inChars[i]))
{
uCWithAnyLC.Add(i - 1);
break;
}
}
}
}
}
char[] outChars = new char[inChars.Length + uCWithAnyLC.Count];
int lastIndex = 0;
for (i=0;i<uCWithAnyLC.Count;i++)
{
int currentIndex = uCWithAnyLC[i];
Array.Copy(inChars, lastIndex, outChars, lastIndex + i, currentIndex - lastIndex);
outChars[currentIndex + i] = ' ';
lastIndex = currentIndex;
}
int lastPos = lastIndex + uCWithAnyLC.Count;
Array.Copy(inChars, lastIndex, outChars, lastPos, outChars.Length - lastPos);
return new string(outChars);
}
Что было самым удивительным, так это тесты производительности. используя 1 000 000 итераций для каждой функции
regex pattern used = "([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))"
test string = "TestTLAContainingCamelCase":
static regex: 13 302ms
Regex instance: 12 398ms
compiled regex: 12 663ms
brent(above): 345ms
AndyRose: 1 764ms
DanTao: 995ms
метод экземпляра Regex был лишь немного быстрее статического, даже более миллиона итераций (и я не вижу преимущества использования флага RegexOptions.Compiled), а очень лаконичный код Дэна Тао был почти таким же быстрым, как мой гораздо менее понятный код!