• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 927
  • Last Modified:

C# ProperCase function that handles McDonalde

I need a ProperCase function that handles McDonald and ONeils?
I have a 'standard' on. Does any one have one that converts  MCDONALD to McDonald ?
  • 2
1 Solution
I didn't have one, but writing it was an interesting challenge :-) It certainly isn't one of the fastest, but it's probably one of the most readable and configurable ones. Tailor to your needs. The algorithm isn't exactly perfect, but I couldn't come up with a situation where the flaws would've mattered in practice.

using System.Text.RegularExpressions;


// The following words will always be in lower case (except in the start of the string)
static string[] lowerCaseWords = { "of", "the", "and", "or", "a", "an", "von" };

// The following prefixes will cause their next character to be uppercased
// Note: Keep the first character uppercase when defining these; all else must be in lowercase
static string[] upperCasePrefixes = { "Mc", "O'" };

// The following words will be always presented in the case they have here.
static string[] fixedCaseWords = { "USA", "NATO", "Mbit" };

/// <summary>
/// Converts the given string into ProperCase.
/// </summary>
/// <param name="original">The original string, f.e. "THE EYE OF THE TIGER"</param>
/// <returns>The string converted into ProperCase, f.e. "The Eye of the Tiger"</returns>
public static string ProperCase(string original) {

  if (original == null || original.Length == 0) return "";

  // Run the original through the massage word-by-word
  string result =
    Regex.Replace(original.ToLower(), @"\b(\w+)\b", new MatchEvaluator(HandleSingleWord));

  // Always uppercase the first character
  return Char.ToUpper(result[0]) + (result.Length > 1 ? result.Substring(1) : "");

// This helper method properizes (sp?) the case of a single word (regex match)
// NOTE: The input is in all lowercase as forced by the ProperCase method.
private static string HandleSingleWord(Match m) {

  string word = m.Groups[1].Value;

  // Is this word defined as all-lowercase?
  foreach (string lcw in lowerCaseWords)
    if (word == lcw)
      return word;

  // Is this word defined as a fixed-case word?
  foreach (string fcw in fixedCaseWords)
    if (String.Compare(word, fcw, true) == 0)
      return fcw;

  // Ok, this is a normal word; uppercase the first letter
  if (word.Length == 1)
    return Char.ToUpper(word[0]).ToString();
  word = Char.ToUpper(word[0]) + word.Substring(1);

  // Check if this word starts with one of the uppercasing prefixes
  // Note: Only one of the uppercasing prefixes is applies
  foreach (string ucPrefix in upperCasePrefixes)
    if (word.StartsWith(ucPrefix) && word.Length > ucPrefix.Length)
      return word.Substring(0, ucPrefix.Length) +
              Char.ToUpper(word[ucPrefix.Length]) +
              (word.Length > ucPrefix.Length + 1
                ? word.Substring(ucPrefix.Length + 1)
                : "");

  return word;
Actually, that Mbit was a stupid example. Substitute "MHz" to see some real effect. :-)
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Train for your Pen Testing Engineer Certification

Enroll today in this bundle of courses to gain experience in the logistics of pen testing, Linux fundamentals, vulnerability assessments, detecting live systems, and more! This series, valued at $3,000, is free for Premium members, Team Accounts, and Qualified Experts.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now