Hi y'all

A while back I requested help for properly capitalizing names out of
passed string values, as ucwords() and tokenizing didn't do the trick.

Some kind soul gave me this scripple to work with:

> $text = "What?No delimiters,shit happens here.this solves all problems.";
> preg_match_all("/(\w+[,. ?])+/U", $text, $words);
> foreach($words[0] as $part) $uwords[] = ucfirst($part);
> $text = implode("", $uwords);
> echo $text;

Which didn't work at all (even changing the variables to match my own),
but only got me several errors for each line...

My task was to make it take a string like
"firstname_middlename_firstlastname-lastlastname" and properly capitalize
it. Also wanted it to do it correctly with names like O'Connor, MacEnroe,
McCarthy and such... The scribble above would be able to do it with the
O'Connors and name-name formats, but useless with Mac/Mc names ... plus
the above script part didn't work at all on my system (PHP 4.2.3 on Apache
2.0.40 on WinXP Pro).

OK ... so I wanted a compact structure that could do this easily, and
correctly, on ANY name I threw at it...so I've spent a couple of hours
finding useful functions in PHP that would do the trickery easiest ... and
ended up with this:

$name = $HTTP_GET_VARS['name'];

// pull real name out of $name
$realname = "";
// okay, let's get the names cap'ed correctly...
$startat = 0; // these vars are used for substring pulling
$stoplen = 0;
// parse 1, find funny chars and cap after them
for ($i = 0; $i < strlen($name); $i++) {
   $ltr = substr($name, $i, 1); // pull out letter i of name
   $stoplen = $i - $startat;  // set the stop point for substring
   // if current letter is a marker
   if ($ltr == "_" | $ltr == "-" | $ltr == "'") {  
      // add substring
      $realname .= ucfirst(substr($name, $startat, $stoplen));  
      $startat = $i + 1;  // set new start point for substring
   }
   if ($ltr == "_") {  // if space, add space
      $realname .= " ";
   }
   elseif ($ltr == "-") { // if dash, add dash
      $realname .= "-";
   }
   elseif ($ltr == "'") {
      $realname .= "'";
   }
}
// the last name won't be added in parse 1,
// this piece adds the last name AFTER checking and capping for Mac/Mc
// so this is essentially pass 2
$lastname = substr($name, $startat, $stoplen + 1);
// find Mac/Mc
$maclen = 0; // we set this to zero to make it easier to check for found
if (strstr($lastname, "mc") != false) {  // if Mc is found...
   $maclen = 2;
}
elseif (strstr($lastname, "mac") != false) {  // if Mac is found
   $maclen = 3;
}
if ($maclen > 0) {  // add the MacSomething with proper capitalization
   $realname .= ucfirst(substr($lastname, 0, $maclen));
   $realname .= ucfirst(substr($lastname, $maclen, strlen($lastname)));
}
else { // if we can't find Mac/Mc, just add the last name...
   $realname .= ucfirst($lastname);
}
// end namegame

The curious thing is that this actually runs faster than the strtok() +
ucwords() combo I had before, plus it does the trick correctly, everytime.
If anyone can see a more efficient way of doing this, I'm all for it.

Do note that I've intentionally made it so that the last word of all names
won't be added to the $realname, until it's determined whether or not it
starts with Mac/Mc. The point to this is simple: It's a lot more
complicated to scan for the Mac/Mc after the full name is assembled, than
it is while it's being built. My structure also ensure that if someone's
called something like Mackenzie for first name, it will not be incorrectly
cap'ed, as it only does the scotch-check on the last names...

If you can do this simpler, or have any comments for this way of doing it,
please let me know. You may freely copy and dsitribute this as you wish.

Rene
-- 
Rene Brehmer
System developer in the making...

This message was written on 100% recycled spam.

Come see! My brand new site is now online!
http://www.metalbunny.net

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to