4

I've been looking around on how to use JavaScript to set names to proper case, e.g. george mchall would become George McHall. I was able to find a write up on Codeproject on how to do this, as well as a person that intended it to do this:

function toProperCase(s){
    return s.toLowerCase().replace( /\b((m)(a?c))?(\w)/g,
    function($1, $2, $3, $4, $5) {
  if($2){
   return $3.toUpperCase()+$4+$5.toUpperCase();
  } 
  return $1.toUpperCase(); 
 });
}

This allows for what I'm looking for. But I need to be able to extend it further and add additional cases.

I found another page on John Gruber's site doing title case, but I'm only looking at doing names.

So, does anyone have an idea on extending it? I'm really just looking for a point in the right direction.

Edit: Since I seem to be hitting a wall here, maybe someone has a way to do it server side. This is at least for now using ColdFusion for the server side. I've seen a C# implementation, but I'm not able to move to C# at the moment.

Tim Meers
  • 928
  • 1
  • 14
  • 24
  • 5
    It's more complicated a problem than it may appear at first glance. You will have to allow for cases beyond Mac/Mc. For example, O'Brien, D'Agostino, LaSalle, etc. Regex may not prove to be the best tool for this. You may have to resort to some kind of dictionary. – Robusto Nov 09 '10 at 14:12
  • It already accounts for names with ' and - because the regex is counting those as a new word after the hyphen or apostrophe. And the regex is already accounting for the Mc/Mac. I'm really looking to account for the La* cases. Anythinh I'm then missing I *should* know how to add once I figure out how to continue to extend it. It's also nothing mission critical, I'm just trying to catch as many as possible for a consistent output. – Tim Meers Nov 09 '10 at 14:23
  • Consider also the various latin names, like "Oscar de la Renta" where it's incorrect for the "de" and "la" to be capitalized. – T.J. Crowder Nov 09 '10 at 14:24
  • @T.J. Crowder that is true. I'm not sure how many there are here though. This is for an internal app, again nothing mission critical, just trying to weed out the **SMITH** vs **smith** vs Smith. – Tim Meers Nov 09 '10 at 14:26
  • ..and Germanic names such as "Michael von der Heiden". – Piotr Rochala Nov 09 '10 at 14:29
  • 1
    @Tim: the problem is differentiating between surnames like Lasseter and LaSalle. That's not something you can do with regex. – Andy E Nov 09 '10 at 14:42
  • That is true....I guess I may have to leave it with this inconsistent user input then. Or perhaps leave it fixing most names and break the few that type it correctly, and are special cases like you said @Andy. Unless it might be wise to check like @Nathan MacInnes says in his answer, then "correct it" if it's all lower/upper. – Tim Meers Nov 09 '10 at 14:56
  • @Tim: yes, that sounds like a viable alternative. Often, people with strangely cased names are rather anal about the casing and ensure they type it correctly into online forms. If you fix only the all-lowercase or all-uppercase, you're reducing the possibility of "fixing" something that's not broken. – Andy E Nov 09 '10 at 14:59
  • Done and done. Of course there is still going to be the left over edge cases of the hanging shift key to which I myself and often guilty when I get going to fast. Guess that will be an admin function to fix names...yeah more work. – Tim Meers Nov 09 '10 at 15:04
  • 1
    @Tim Meers: Just thought of another ugly exception for you. Google "Jerald terHorst", who was press secretary for Gerald Ford. I think you'll find there is no "perfect" way to accomplish this with regular expressions. – Robusto Nov 10 '10 at 13:43
  • @Robusto that is correct I completely digress on this. However I have come to the conclusion that I can at least catch the "low hanging fruit" and attempt to make it consistent by only "correcting" those names all in lower or in upper case i.e. SMITH or smith would get corrected as Smith but I'm not looking at SMith or even SmiTH either. – Tim Meers Nov 10 '10 at 14:03

2 Answers2

6

Combining a few answers from similar posts:

    var selElem = document.getElementById("fromName");

    selElem.addEventListener("change", function() {
      document.getElementById("result").innerHTML = properName(selElem.value);
    });

    function properName(name) {
      return ("" + name.replace(/[^\s\-\']+[\s\-\']*/g, function(word) {
        return word.charAt(0).toUpperCase() + word.substr(1).toLowerCase();
      }).replace(/\b(Van|De|Der|Da|Von)\b/g, function(nobiliaryParticle) {
        return nobiliaryParticle.toLowerCase();
      }).replace(/Mc(.)/g, function(match, letter3) {
        return 'Mc' + letter3.toUpperCase();
      }));
    }
<p>
  Choose a name to see it properly capitalised:
</p>
<select id="fromName">
  <option>Select a name</option>
  <option>EMMA HURST</option>
  <option>CHRIS HINDI</option>
  <option>OSCAR GRENFELL</option>
  <option>JIM CASEY</option>
  <option>MEOW-LUDO DISCO GAMMA MEOW-MEOW</option>
  <option>PAT SHEIL</option>
  <option>NOEL MCFARLANE</option>
  <option>CHRIS MCLACHLAN</option>
  <option>ANTHONY ALBANESE</option>
  <option>DAVID VAN GOGH</option>
  <option>JAMIE ELVY</option>
</select>
<p>Result: <span id="result"></span></p>
Mohsen Alyafei
  • 4,765
  • 3
  • 30
  • 42
jondoig
  • 181
  • 2
  • 6
3

How about this:

if (str==str.toLowerCase() || str==str.toUpperCase())
  str = str.toTitleCase();

Otherwise, leave it well alone!!!

Edit: You could optionally split the string to weed out people holding the shift key for too long, like SMith.

Nathan MacInnes
  • 11,033
  • 4
  • 35
  • 50
  • After discussion in the question comments this is the "best" solution. However the `toTitleCase()` does not work at all for me. Perhaps elaborating your answer would help. – Tim Meers Nov 09 '10 at 15:06
  • Sorry, thought it was a built-in function. Here's an implementation that'll make it work: http://individed.com/code/to-title-case/js/to-title-case.js – Nathan MacInnes Nov 09 '10 at 15:57
  • Taking this as my answer because it's "good enough" and should attempt at least to catch the caps lock offenders which seems to be the widest offending group. – Tim Meers Nov 10 '10 at 14:07
  • Yup, "good enough" is what I've found when I've done this in PHP. It's just impossible to account for every possible mixed-case surname. – Nathan MacInnes Nov 10 '10 at 14:19