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