I already do this server-side on page load. Wrote a Coldfusion CFC that gets two params passed to it - actual user data(first name, middle, last name) and data type(first,middle,last). Then routine checks for hyphens, apostrophes, spaces and formats accordingly. ex. MacDonald, McMurray, O'Neill, Rodham-Clinton, Eric von Dutch, G. W. Bush, Jack Burton Jr., Dr. Paul Okin, Chris di Santos. For case where users only have one name, only the first name field is required, middle and last names are optional.
All info is stored lowercase - except Prefix, Suffix and Custom. This formatting is done on page render, not during store to db. Though there is validation filtering when user inputs data. Sorry, cannot post code. Started out using Regex but became too confusing and unreliable for all scenarios. Used standard logic blocks(if/else, switch/case), easier to read and debug. MAKE EVERY INPUT/DB FIELD SEPARATE! Yes, this will take some coding, but after you are finished it should account for 99% of combinations. Only based on English names so far, no internationalization, that's another ball of wax.
Here's some things to consider:
- Hypens (ex. Rodham-Clinton, could be in first, middle or last)
- Apostrophes (ex. O'Neill, could be in first, middle or last)
- Spaces
- Mc and Mac (ex. McDonald, MacMurray, could be in first, middle or
last)
- First names: multiple first names (ex. Joe Bob Briggs)
- Last names: de,di,et,der,den,van,von,af should be lowercase (ex Eric
von Dander, Mary di Carlo)
- Prefix: Dr., Prof., etc
- Suffix: Jr., Sr., Esq., II, III, etc
When user enters info, field schema in db is like so:
- Prefix/Title (Dr., etc using a dropdown)
- Prefix/Title Custom (user can enter custom, ex. Capt. using a text
field)
- First Name
- Middle
- Last Name
- Suffix (Jr., III, Prof., Ret., etc using a dropdown)
- Suffix Custom (user can enter custom, ex. CPA)
Here's the one Regex I do use to make first letter of each name uppercase. I run this first, then following routines format according to rules(it's in Coldfusion format but you get the idea):
<cfset var nameString = REReplace(LCase(nameString), "(^[[:alpha:]]|[[:blank:]][[:alpha:]])", "\U\1\E", "ALL")>
You could also do this client-side using JavaScript and CSS - might even be easier - but I prefer to do server-side since I need the variables set before page loads client-side.