using System.Globalization;
using System.Text.RegularExpressions;
public static void Main()
DisplayOutputs("love ASP .net");
DisplayOutputs("PeaCe aNd WaR");
DisplayOutputs("Mr. McGregor");
DisplayOutputs("Artis-Payne");
DisplayOutputs("sing-a-long");
DisplayOutputs("a.b,c/d[e]f_g{h}i=j!k@l`m~n#o$p%q^r&s(t)u|v?w*x<y>z:a;b");
DisplayOutputs("7up 21st");
DisplayOutputs("7up __st");
DisplayOutputs(" space start");
private static void DisplayOutputs(string input)
Console.WriteLine($"--------------Outputs for {input}----------------");
var textInfo = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo;
Console.WriteLine(textInfo.ToTitleCase(input) + " -- Expected Output");
Console.WriteLine(input.ToTitleCaseAnswer3() + " --Tokenizer with split and character inspection");
Console.WriteLine(input.ToTitleCaseAnswer1() + " --Simple tokenizer with split");
Console.WriteLine(input.ToTitleCaseAnswer2() + " --Regex and TextInfo");
public static class StringHelper
private static readonly CultureInfo _cultureInfo = CultureInfo.InvariantCulture;
public static string ToTitleCaseAnswer1(this string str)
var tokens = str.Split(new[]{" "}, StringSplitOptions.RemoveEmptyEntries);
for (var i = 0; i < tokens.Length; i++)
if (token == token.ToUpper())
else if (token[0] == '-')
tokens[i] = "-" + token.Substring(1, 2).ToUpper() + token.Substring(2).ToLower();
tokens[i] = token.Substring(0, 1).ToUpper() + token.Substring(1).ToLower();
return string.Join(" ", tokens);
public static string ToTitleCaseAnswer3(this string str)
var tokens = str.Split(new[]{" "}, StringSplitOptions.None);
var stringBuilder = new StringBuilder();
for (var ti = 0; ti < tokens.Length; ti++)
if (token == token.ToUpper())
stringBuilder.Append(token + " ");
var previousWasSeperator = false;
var previousWasNumber = false;
var ignoreNumber = false;
for (var i = 0; i < token.Length; i++)
if (char.IsNumber(token[i]))
stringBuilder.Append(token[i]);
previousWasNumber = true;
else if (!char.IsLetter(token[i]))
stringBuilder.Append(token[i]);
previousWasSeperator = true;
else if ((previousWasNumber && !ignoreNumber) || previousWasSeperator)
stringBuilder.Append(char.ToUpper(token[i]));
previousWasSeperator = false;
previousWasNumber = false;
stringBuilder.Append(char.ToUpper(token[i]));
stringBuilder.Append(char.ToLower(token[i]));
stringBuilder.Append(" ");
return stringBuilder.ToString().TrimEnd();
public static string ToTitleCaseAnswer2(this string str)
var tokens = Regex.Split(_cultureInfo.TextInfo.ToLower(str), "([ -])");
for (var i = 0; i < tokens.Length; i++)
if (!Regex.IsMatch(tokens[i], "^[ -]$"))
tokens[i] = $"{_cultureInfo.TextInfo.ToUpper(tokens[i].Substring(0, 1))}{tokens[i].Substring(1)}";
return string.Join("", tokens);