bcmcfc
bcmcfc

Reputation: 26765

Nice easy way of capitalizing names such as "o'sullivan"?

Take two strings:

"o'sulLivAn"
"doUble-baRrel"

Desired result:

"O'Sullivan"
"Double-Barrel"

I thought ucwords(strtolower($str)) might do the trick but it treats the strings as a single word.

I know I can explode, or rather preg_split the string and then capitalize the parts and put it back together again, but I'm wondering if there's a better way of doing it?

Usually with PHP and this sort of thing there tends to be a function hiding away somewhere that'd be useful but isn't obvious or well known.

Upvotes: 0

Views: 251

Answers (3)

Hannes
Hannes

Reputation: 8237

You can use preg_replace_callback() here:

function upcaseLetters(string $line): string {
    return preg_replace_callback('#^[\w]|[\W][\w]#', function ($match) {    
        return strtoupper($match[0]);
    }, strtolower($line));
}

Usage Example:

$lines = [
    "o'sulLivAn",
    "doUble-baRrel",
];

foreach ($lines as $line) {
    echo upcaseLetters($line), "\n";
}

Demo: https://3v4l.org/l8BKF

Outputs:

O'Sullivan
Double-Barrel

Reference:

Upvotes: 3

Matthew
Matthew

Reputation: 48294

If you don't mind the e modifier (deprecated in 2016):

preg_replace('!(^|\W)[a-z]!e', "strtoupper('\\0')", strtolower($text));

Upvotes: 0

Galen
Galen

Reputation: 30170

There's no php function to do this.

Here's a one-liner with no loop (kinda)

$str1 = "double-barrel";
$str2 = "o'sulLivAn";


function my_ucase( $str, $chars="-'" ) {
    return implode(array_map( 'ucwords', array_map( 'strtolower', preg_split( "~([".$chars."])~", $str, null, PREG_SPLIT_DELIM_CAPTURE ))));
}

echo my_ucase($str1);
echo my_ucase($str2);

Upvotes: 1

Related Questions