Skip to content

Title-case a string

This operation converts a free-text string to title case using a domain-specific algorithm rather than .NET's built-in proper-case conversion. It renders configured abbreviations, minor words, and mixed-case exceptions in a fixed casing, preserves already-mixed-case words, formats numeric ordinals, and applies a possessive-suffix pass — producing more accurate casing for names, addresses, and organization names than a naive proper-case conversion.

Field Value
Operation ID OP-BU-01
Trigger Caller calls TitleCase.ToTitleCase(inString) directly, or inString.ToTitleCase() via the extension method, which simply forwards to TitleCase.ToTitleCase
Inputs inString As String
Outputs Title-cased String
Primary components TitleCase.ToTitleCase, TitleCase.TitleCaseSingleWord, TitleCase.ReassembleString, TitleCase.ApplyExactSuffixList, TitleCase.HasNumberSuffix, TitleCase.GetNumberSuffixParts, TitleCaseExtensions.ToTitleCase
Entry point Business\SAIF.Business.Utilities\TitleCase.vb

Steps

  1. Handle empty input. If inString is Nothing or trims to zero length, return it unchanged with no further processing.
  2. Split the string into words. Split inString.Trim on any character that is not a letter or digit (Regex.Split(inString.Trim, "[^\d\w]")), preserving the delimiter characters for later reassembly.
  3. Classify each split word, in order of precedence:
  4. If the word already contains both an uppercase and a lowercase character, return it unchanged. (BR-003)
  5. Else if the word (uppercased) matches the configured UpperCaseWordList (abbreviations such as "SAIF", "LLC", "MD", state codes), render it fully uppercase. (BR-001)
  6. Else if the word (lowercased) matches the configured LowerCaseWordList (minor words such as "is", "in", "the", "of"), render it fully lowercase. (BR-001)
  7. Else if the word (lowercased) matches the configured MixedCaseWordList (exceptions such as "PhD", "LaCombe"), render it using the configured mixed-case spelling. (BR-001)
  8. Else if the word is a number followed by a recognized ordinal suffix (st, nd, rd, th), render the numeral with a lowercase suffix. (BR-004)
  9. Else, apply the default proper-case algorithm (word.ToProperCase).
  10. Apply mixed-case prefix handling. If the classified word starts with a configured prefix (Mc, O'), proper-case only the portion after the prefix and keep the prefix as configured.
  11. Reassemble the string. Recombine the classified words with the original non-alphanumeric delimiter characters from the source string, preserving any leading delimiters.
  12. Apply the exact-suffix pass. Split the reassembled string on spaces and, for each word ending in a configured suffix (currently only the possessive 's), force that suffix to its configured lowercase form. (BR-005)
  13. Force the leading character to uppercase. Regardless of the outcome of the prior steps, the first character of the final output string is always uppercased before it is returned.*

Process flow

The following diagram visualizes the word-classification precedence and reassembly used by this operation.

flowchart TD
    Start([Start: ToTitleCase]) --> Empty{Input null or blank?}
    Empty -->|Yes| ReturnAsIs([Return input unchanged])
    Empty -->|No| Split[Split input into words<br>on non-alphanumeric delimiters]
    Split --> Classify{Classify each word}
    Classify -->|Already mixed case| Unchanged[Return word unchanged]
    Classify -->|Uppercase word list| U[Render fully uppercase]
    Classify -->|Lowercase word list| L[Render fully lowercase]
    Classify -->|Mixed-case word list| M[Render per configured spelling]
    Classify -->|Numeric ordinal| N[Render numeral with lowercase suffix]
    Classify -->|No match| P[Apply default proper-case algorithm]
    Unchanged --> Prefix{Starts with configured prefix?}
    U --> Prefix
    L --> Prefix
    M --> Prefix
    N --> Prefix
    P --> Prefix
    Prefix -->|Yes| PrefixApply[Proper-case only the text after the prefix]
    Prefix -->|No| Reassemble[Reassemble string with original delimiters]
    PrefixApply --> Reassemble
    Reassemble --> Suffix[Force configured possessive<br>suffix to lowercase]
    Suffix --> Upper[Force leading character to uppercase]
    Upper --> End([Return title-cased string])

Failure and edge-case behavior

  • Empty or Nothing input is returned unchanged without throwing.
  • Words that are already a mix of uppercase and lowercase characters are never re-cased, even if they also happen to match a configured word list. (BR-003)
  • The final output's leading character is always uppercased, even if word classification would otherwise have rendered it lowercase (e.g., a minor word at the start of the string).*
  • The exact-suffix pass operates on the string split by single spaces; the delimiter-preservation from step 2 could still leave non-space delimiters embedded in a "word" as split for this pass, which is not exercised by the possessive-suffix case currently configured.*

Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.

Sources

  • Business\SAIF.Business.Utilities\TitleCase.vb