17

The .NET Framework has a method TextInfo.ToTitleCase.

Is there something equivalent in .NET Core?

Edit: I'm looking for a built-in method in .NET Core.

4

6 Answers 6

26

You can implement your own extension method:

public static class StringHelper
{
    public static string ToTitleCase(this string str)
    {
        var tokens = str.Split(new[] { " ", "-" }, StringSplitOptions.RemoveEmptyEntries);
        for (var i = 0; i < tokens.Length; i++)
        {
            var token = tokens[i];
            tokens[i] = token == token.ToUpper()
                ? token 
                : token.Substring(0, 1).ToUpper() + token.Substring(1).ToLower();
        }

        return string.Join(" ", tokens);
    }
}

Credit: blatently copied form this gist*.

*Added the bit for acronyms Dotnet Fiddle.

5
  • This does not do "proper" title casing, however the old .net method did not either.
    – mxmissile
    Commented Jul 13, 2016 at 20:24
  • 4
    the OP request a replacement for TextInfo.ToTitleCase, not for a proper title casing, so this answer is correct. And also works well.
    – T-moty
    Commented Jul 29, 2016 at 10:08
  • This solution doesn't handle all of the cases that ToTitleCase handled. See my solution. Commented Jul 15, 2017 at 0:34
  • Why would you convert all instances of - to ` `? That's clearly a bug. Commented Nov 9, 2017 at 16:15
  • @MahmoudAl-Qudsi Did you read the rest of the code? Did you actually try running it?
    – mxmissile
    Commented Nov 9, 2017 at 16:38
12

.NET Standard 2.0 added TextInfo.ToTitleCase (source), so you can use it in .NET Core 2.0.

For .NET Core 1.x support, however, you are out of luck.

11

It seems there is no such method built-in to .NET Core.

2

Unfortunately, still in October 2016, .NET Core does not provide us with a ToTitleCase method.

I created one myself that works for my own needs. You can adjust it by adding your own delimiters to the regular expressions. Replace _cultureInfo with the CultureInfo instance that is applicable to you.

public static class TextHelper
{
     private static readonly CultureInfo _cultureInfo = CultureInfo.InvariantCulture;

     public static string ToTitleCase(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);
     }
 }
4
  • Try removing the ToLower() method if that works for your specific needs.
    – silkfire
    Commented Jul 14, 2017 at 19:40
  • I don't know what you mean? Removing ToLower causes compilation errors. ToLower and ToUpper are the only options I see. Again this solution doesn't handle acronyms. Commented Jul 14, 2017 at 20:56
  • Throws an exception on strings terminating with whitespace. Commented Nov 9, 2017 at 16:17
  • @MahmoudAl-Qudsi I guess a proper .Trim() around the string at the beginning of the method would do the trick?
    – silkfire
    Commented Nov 9, 2017 at 21:54
2

I created a github for the extension with tests, and a dotnet fiddle that includes the other solutions from this post. You will have to uncomment to lines to see what the other solutions output. This solution has covered all scenarios that came to mind. You can verify these in the tests on the git or on the fiddle. I suggest you use this solution if you want to get similar output to the TextInfo.ToTitleCase in non .NET Core.

 public static class StringExtension
{
    /// <summary>
    /// Should capitalize the first letter of each word. Acronyms will stay uppercased.
    /// Anything after a non letter or number will keep be capitalized. 
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static string ToTitleCase(this string str)
    {
        var tokens = str.Split(new[] { " " }, StringSplitOptions.None);
        var stringBuilder = new StringBuilder();
        for (var ti = 0; ti < tokens.Length; ti++)
        {
            var token = tokens[ti];
            if (token == token.ToUpper())
                stringBuilder.Append(token + " ");
            else
            {
                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;
                    }
                    else if (i == 0)
                    {
                        ignoreNumber = true;
                        stringBuilder.Append(char.ToUpper(token[i]));
                    }
                    else
                    {
                        ignoreNumber = true;
                        stringBuilder.Append(char.ToLower(token[i]));
                    }
                }
                stringBuilder.Append(" ");
            }
        }
        return stringBuilder.ToString().TrimEnd();
    }
}
0

This worked for me in .net core

 public static string ToTitleCase(this string str)
        {
            try
            {
                var tokens = str.Split(new[] { " ", "-" }, StringSplitOptions.RemoveEmptyEntries);
                string final = "";

                for (var i = 0; i < tokens.Length; i++)
                {
                    var token = tokens[i];

                    string first = token.Substring(0, 1);
                    string remaining = token.Substring(1, token.Length - 1);

                    final +=  first.ToUpper() + remaining.ToLower()+" ";

                }

                return final;
            }
            catch {
                return "";
            }
        }

Not the answer you're looking for? Browse other questions tagged or ask your own question.