views:

46

answers:

5

I need to turn names that are always in lower case into uppercase.

e.g. john johnsson -> John Johnsson

but also:

jonny-bart johnsson -> Jonny-Bart Johnsson

How do I accomplish this using PHP?

+1  A: 
<?php
//FUNCTION

function ucname($string) {
    $string =ucwords(strtolower($string));

    foreach (array('-', '\'') as $delimiter) {
      if (strpos($string, $delimiter)!==false) {
        $string =implode($delimiter, array_map('ucfirst', explode($delimiter, $string)));
      }
    }
    return $string;
}
?>
<?php
//TEST

$names =array(
  'JEAN-LUC PICARD',
  'MILES O\'BRIEN',
  'WILLIAM RIKER',
  'geordi la forge',
  'bEvErly CRuSHeR'
);
foreach ($names as $name) { print ucname("{$name}\n"); }

//PRINTS:
/*
Jean-Luc Picard
Miles O'Brien
William Riker
Geordi La Forge
Beverly Crusher
*/
?>

From comments on the PHP manual entry for ucwords.

Dominic Rodger
Note that this initially lowercases the whole string, which may or may not be what you want - you can always remove the `strtolower` call if it's not what you want.
Dominic Rodger
+1  A: 

with regexps:

$out = preg_replace_callback("/[a-z]+/i",'ucfirst_match',$in);

function ucfirst_match($match)
{
    return ucfirst(strtolower($match[0]));
}
mvds
i would use a `preg_replace_callback` was coming on here to write this but beat me to it.. +1
RobertPitt
+3  A: 

You could also use a regular expression:

preg_replace_callback('/\b\p{Ll}/', 'callback', $str)

\b represents a word boundary and \p{Ll} describes any lowercase letter in Unicode. preg_replace_callback will call a function called callback for each match and replace the match with its return value:

function callback($match) {
    return mb_strtoupper($match[0]);
}

Here mb_strtoupper is used to turn the matched lowercase letter to uppercase.

Gumbo
I like this one, but I think there is a danger to advocating the /e modifier on public forums like these, where unexperienced programmers will not see the clear dangers of it.
mvds
@mvds: I changed it to use `preg_replace_callback` instead.
Gumbo
great, +1 then ;-)
mvds
+1  A: 

If you're expecting unicode characters...or even if you're not, I recommend using mb_convert_case nonetheless. You shouldn't need to use preg_replace when there's a php function for this.

Lyon
A: 

Here's what I came up with (tested)...

$chars="'";//characters other than space and dash
           //after which letters should be capitalized

function callback($matches){
    return $matches[1].strtoupper($matches[2]);
}

$name="john doe";
$name=preg_replace_callback('/(^|[ \-'.$chars.'])([a-z])/',"callback",$name);

Or if you have php 5.3+ this is probably better (untested):

function capitalizeName($name,$chars="'"){
    return preg_replace_callback('/(^|[ \-'.$chars.'])([a-z])/',
        function($matches){
            return $matches[1].strtoupper($matches[2]);
        },$name);
}

My solution is a bit more verbose than some of the others posted, but I believe it offers the best flexibility (you can modify the $chars string to change which characters can separate names).

Cam