patterncsharpModerate
Extension method splitting string on each capital letter
Viewed 0 times
eachmethodsplittingextensionletterstringcapital
Problem
I'm creating my own game and for some statistics I need to get the names of specific objects. The problem was that I had them declared like "SmallFireBall" but I wanted them to appear like"Small Fire Ball" because that's something the user is able to see, so I decided to create my own extension method to help me out:
However, I'm not quite confident about it. It seems quite big and maybe a little bit ugly, so please address any performance or code style issues.
public static string SplitOnCapitalLetters(this string inputString)
{
List cleanString = inputString.ToList();
for (int i = 1; i < cleanString.Count; i++)
{
if (char.IsUpper(cleanString[i]))
{
char[] temp = new char[cleanString.Count - i];
for (int j = 0; j < temp.Length; j++)
{
temp[j] = cleanString[j + i];
}
cleanString[i] = ' ';
cleanString.Add(' ');
int index = 0;
for (int j = i + 1; j < cleanString.Count; j++)
{
cleanString[j] = temp[index];
index++;
}
i++;
}
}
return new string(cleanString.ToArray());
}However, I'm not quite confident about it. It seems quite big and maybe a little bit ugly, so please address any performance or code style issues.
Solution
With regex it's virtually a one-liner:
Output:
Small Fire Ball
Let's review your code anyway and optimize it a little bit. Even without regex it still can be very short.
-
You can use a
The 3rd alternative would be only LINQ:
var words =
Regex.Matches("SmallFireBall", @"([A-Z][a-z]+)")
.Cast()
.Select(m => m.Value);
var withSpaces = string.Join(" ", words);Regex.Matches- searches an input string for all occurrences of a regular expression and returns all the matches. MSDN
[A-Z][a-z]+- matches strings that begin with a capital letter and are followed by one or more lowercase letters
Output:
Small Fire Ball
Let's review your code anyway and optimize it a little bit. Even without regex it still can be very short.
- Use a
StringBuilderfor building string dynamically
-
You can use a
foreach loop for strings toopublic static string SplitOnCapitalLetters2(this string inputString)
{
var result = new StringBuilder();
foreach (var ch in inputString)
{
if (char.IsUpper(ch) && result.Length > 0)
{
result.Append(' ');
}
result.Append(ch);
}
return result.ToString();
}The 3rd alternative would be only LINQ:
public static string SplitOnCapitalLetters3(this string inputString)
{
// starts with an empty string and accumulates the new string into 'result'
// 'next' is the next character
return inputString.Aggregate(string.Empty, (result, next) =>
{
if (char.IsUpper(next) && result.Length > 0)
{
result += ' ';
}
return result + next;
});
}Code Snippets
var words =
Regex.Matches("SmallFireBall", @"([A-Z][a-z]+)")
.Cast<Match>()
.Select(m => m.Value);
var withSpaces = string.Join(" ", words);public static string SplitOnCapitalLetters2(this string inputString)
{
var result = new StringBuilder();
foreach (var ch in inputString)
{
if (char.IsUpper(ch) && result.Length > 0)
{
result.Append(' ');
}
result.Append(ch);
}
return result.ToString();
}public static string SplitOnCapitalLetters3(this string inputString)
{
// starts with an empty string and accumulates the new string into 'result'
// 'next' is the next character
return inputString.Aggregate(string.Empty, (result, next) =>
{
if (char.IsUpper(next) && result.Length > 0)
{
result += ' ';
}
return result + next;
});
}Context
StackExchange Code Review Q#133707, answer score: 19
Revisions (0)
No revisions yet.