Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : String Functions : ucwords

ucwords

Uppercase the first character of each word in a string (PHP 4, PHP 5)
string ucwords ( string str )

Example 2483. ucwords() example

<?php
$foo
= 'hello world!';
$foo = ucwords($foo);             // Hello World!

$bar = 'HELLO WORLD!';
$bar = ucwords($bar);             // HELLO WORLD!
$bar = ucwords(strtolower($bar)); // Hello World!
?>

Related Examples ( Source code ) » ucwords



Code Examples / Notes » ucwords

fille

[Editor's note: For details on the bug see
http://bugs.php.net/bug.php?id=14655]
This function has a bug, and while waiting for the bug fix, here is a work-around pice of code.
When using international letters, you will get into troubles with the ucwords() function.
Example:
$string="xxxöxx" will be "XxxöXxx" after beeing processed by ucwords().
To get around it, I wrote some extra code that checks the string once more, and lowercases all letters that is not in the beginning of a word.
$string=ucwords($string);
//Bugfix from here on
for($i=0;$i<strlen($string);$i++)
if((ctype_upper($string[$i]) &&( $string[$i-1]==" " || $i==0 ))!=TRUE)
$string[$i]=strtolower($string[$i]);
Thia code is also an optional way of doing the same work on a string that is totally UPPERCASE.


ieure

Whoa guys, tone things down a bit here. No need to loop and implode. This is a one-line solution:
function ucsmart($text)
{
   return preg_replace('/([^a-z]|^)([a-z])/e', '"$1".strtoupper("$2")',
                       strtolower($text));
}
igua's code adds a backslash in front of the first single quote for me. This doesn't alter the content in any way other than changing case.


q1712

ucwords() only excepts whitespace in front of a word, although some chars like '"' or '(' normally have no space between them and the following word:
<?php
$title = 'ELVIS "THE KING" PRESLEY - (LET ME BE YOUR) TEDDY BEAR';
echo ucwords(strtolower($title));
?>
prints: Elvis "the King" Presley - (let Me Be Your) Teddy Bear
To avoid this i use a small function adding and deleting blanks behind these chars, and using ucwords() in between:
<?php
function my_ucwords($string)
 {
   $noletters='"([/'; //add more if u need to
   for($i=0; $i<strlen($noletters); $i++)
     $string = str_replace($noletters[$i], $noletters[$i].' ', $string);
   $string=ucwords($string);
   for($i=0; $i<strlen($noletters); $i++)
     $string = str_replace($noletters[$i].' ', $noletters[$i], $string);
   return $string;
 }
$title = 'ELVIS "THE KING" PRESLEY - (LET ME BE YOUR) TEDDY BEAR';
echo my_ucwords(strtolower($title));
?>
prints: Elvis "The King" Presley - (Let Me Be Your) Teddy Bear


marco

ucwords that works also with apices: '
for example: "aquila d'abruzzo" became "Aquila d'Abruzzo"
The second part after the // comment can removed! Is optimized for italian language (leave lowercase articles, prepositions, conjunctions) but easily changeable. Notice che "'s"!! for example "hotel 2000's" becames "Hotel 2000's".
function my_ucwords($s)
{
$a=strtolower($s);
$s=ucfirst($a);
for($x=0; $x<strlen($s)-1; $x++)
if(!ctype_alpha($s[$x])) $s[$x+1]=strtoupper($s[$x+1]);
//Lascia minuscoli articoli, preposizioni, congiunzioni
$minuscole=array("il", "lo", "la", "i", "gli", "le", //ARTICOLI DETERMINATIVI
"un", "uno", "una", //ARTICOLI INDETERMINATIVI
"e",  "d", "l", "s", "un", //CONGIUNZIONI e CONTRATTI
"di", "a", "da", "in", "con", "su", "per", "tra", "fra", //PREPOSIZIONI SEMPLICI
"del", "dello", "della", "dei", "degli", "delle", //PREPOSIZIONI ARTICOLATE
"a", "al", "allo", "alla", "ai", "agli", "alle",
"da", "dal", "dallo", "dalla", "dai", "dagli", "dalle",
"in", "nel", "nello", "nella", "nei", "negli", "nelle",
"con", "col", "collo", "colla", "coi", "cogli", "colle",
"su", "sul", "sullo", "sulla", "sui", "sugli", "sulle",
"per", "pel", "pei");

foreach($minuscole as $value)
{
$pos=strpos($a, $value);
if( ( $pos>0 && $pos<strlen($s)-1 && !ctype_alpha($a[$pos-1]) && !ctype_alpha($a[$pos+1]) ) //CARATTERE IN MEZZO
||  ( $pos==strlen($s)-1 && !ctype_alpha($a[$pos-1]) ) ) //CASO PARTICOLARE: carattere in fondo. x es: "hotel 2000's"
$s[$pos]=strtolower($s[$pos]);
}
return $s;
}
function my_ucwords_essential($s)
{
$a=strtolower($s);
$s=ucfirst($a);
for($x=0; $x<strlen($s)-1; $x++)
if(!ctype_alpha($s[$x])) $s[$x+1]=strtoupper($s[$x+1]);
return $s;
}
Can be rewritten better, I Know


emailfire

To use ucwords with an exception:
<?php
function ucwordss($str, $exceptions) {
$out = "";
foreach (explode(" ", $str) as $word) {
$out .= (!in_array($word, $exceptions)) ? strtoupper($word{0}) . substr($word, 1) . " " : $word . " ";
}
return rtrim($out);
}
?>
For example:
<?php
$string = "my cat is going to the vet";
$ignore = array("is", "to", "the");
echo ucwordss($string, $ignore);
// My Cat is Going to the Vet
?>


chris

To get some sort of title case with lower-case articles, prepositions etc., try something like this (removing the carriage returns in the regular expression):
<?php
function lower_articles($str) {
return preg_replace(
"/(?<=(?<!:|’s)\W)
(A|An|And|At|For|In|Of|On|Or|The|To|With)
(?=\W)/e",
'strtolower("$1")',
$str
);
}
?>
I added the lookbehind (?<!:|’s) because I use this for film titles, where words following those terms should be capitalised (e.g. Lemony Snicket’s A Series of Unfortunate Events, American Pie Presents: The Naked Mile).


19-jan-2002 02:14

This seems to be what people want:
function uc_all($string) {
   $temp = preg_split('/(\W)/', $string, -1, PREG_SPLIT_DELIM_CAPTURE );
   foreach ($temp as $key=>$word) {
       $temp[$key] = ucfirst(strtolower($word));
   }
   return join ('', $temp);
}
[ed note: fixed the code to be correct]


igua no-spam

The code posted by neil doesn't fully do what is wanted. Try adding some more question marks at the end and it will return a not wanted string.
Below code will uppercase all your words regardless of the delimiter.
<?php
$text = "What?No 'delimiters',shit \"happens\" here.this solves all problems???";
preg_match_all('/[A-Za-z]+|[^A-Za-z]+/', $text, $data);
for ($i = 0; $i < count($data[0]); $i++) {
 $data[0][$i] = ucfirst($data[0][$i]);
}
$text = implode("", $data[0]);
print $text;
?>


neil

The code posted above by Joerg Krause only works for a string which ends with one of the delimiters. A possible fix is:
$text = "What?No delimiters,shit happens here.this solves all problems.";
preg_match_all("/(\w+[,. ?])+/U", $text, $words);
preg_match("/(\w+)$/", $text, $lastword);
$words[0][] = $lastword;
foreach($words[0] as $part) $uwords[] = ucfirst($part);
$text = implode("", $uwords);
echo $text;


starmonkey

Simple helper function to walk through a nested array of strings and upper case them:
<?php
/**
* Helper function to convert an array of strings to upper case words
*/
function _capitalize($input) {
if(is_array($input)) {
// recurse through array elements (using a reference)
foreach($input as &$value) {
$value = _capitalize($value);
}
return $input;
} elseif(is_string($input)) {
// process this string
return ucwords($input);
} else {
// all other data types, leave alone
return $input;
}
}
?>


ismet togay

Response to arif:
We do not need that long functions. In order to make ucwords() worked properly in Turkish words that contain speacial characters, we can use the following command in our php codes:
setlocale(LC_ALL, 'tr_TR');
This will set locale to Turkish.


arjini

Not so much ucwords() related as it is capital letter related. I often use camel casing (as do wikis), I needed a reason to reverse the camel casing.
function unCamelCase($str){
$bits = preg_split('/([A-Z])/',$str,false,PREG_SPLIT_DELIM_CAPTURE);
$a = array();
array_shift($bits);
for($i = 0; $i < count($bits); ++$i)
if($i%2)
$a[] = $bits[$i - 1].$bits[$i];
return $a;
}
print_r(unCamelCase('MyFancyCamelCasedWord'));
Array
(
   [0] => My
   [1] => Fancy
   [2] => Camel
   [3] => Cased
   [4] => Word
)


bobo

Mildly annoying, only spaces are considered whitespace by this function. So words right after linebreaks do not get capitalized. An explode/implode can help here.
$temp = explode ("\n", $capthis);
array_walk (&$temp, ucwords);
$capthis = implode ("\n", $temp);


julienc

Its still possible to clean a bit more the previous sample:
$string=strtolower($string); $break=true;
for ($i=0; $i < strlen($string); $i++) { $subed=$string[$i];
if (((ord($subed) > 64) && (ord($subed) < 123)) || ((ord($subed) > 48) && (ord($subed) < 58))) {
if ($break) { $string[$i] = strtoupper($subed); }
$break=false; } else { $break=true; }
}
- Julien


arif

it can be used for Turkish alphabet.
function strtoupperTR($str){
  return strtr($str,
  "abcçdefgÄŸhıijklmnoöpqrsÅŸtuüvwxyz",
  "ABCÇDEFGÄžHIÄ°JKLMNOÖPQRSÅžTUÃœVWXYZ");
}
function strtolowerTR($str){
  return strtr($str,
  "ABCÇDEFGÄžHIÄ°JKLMNOÖPQRSÅžTUÃœVWXYZ",
  "abcçdefgÄŸhıijklmnoöpqrsÅŸtuüvwxyz");
}
function ucwordsTR($str)
{
  return preg_replace('/([^a-zığüşçö]|^)([a-zığüşçö])/e', '"$1".strtoupperTR("$2")',
                      strtolowerTR($str));
}


lev

In the function ucsmart() posted by ieure at php dot net on 04-Dec-2005 11:57, I found a similar problem in this function to what he found in igua's.
<?php
function ucsmart($text)
{
  return preg_replace('/([^a-z]|^)([a-z])/e', '"$1".strtoupper("$2")',
                      strtolower($text));
}
?>
"igua's code adds a backslash in front of the first single quote for me. This doesn't alter the content in any way other than changing case."
Actually, it did end up changing the content for me (php 5.0.4) in the way that this function escapes a single quotation (apostrophe) in the MIDDLE of a word.
For example:
who's online?
Became:
Who\'s Online?
The fix is simple however, and merely requires fine-tuning the regular expression:
<?php
function ucsmart($text)
{
  return preg_replace('/([^a-z\']|^)([a-z])/e', '"$1".strtoupper("$2")',
                      strtolower($text));
}
?>
(note: while previewing this note before adding it, I am noticing php's website is not correctly displaying the change I made as I wrote it. After the first a-z in the expression, the single quotation should be escaped... If it isn't you will get a parse error! And apoligies if my text here is colored as php code; not my fault!)
This will not escape a single quotation mark which occurs in the middle of a word... Though, you may find that might need to add other characters inside the regular expression if you use other special characters inside your words and if you get funky output.
It's a great expression though! Simple, yet very powerful. Kudos!


radley25

In response to joshuamallory at yahoo dot com:
Using CSS to fix a PHP fault is not the ideal way to solve a problem. CSS is browser dependent and can only be used when the data is presented in a web page. A better fix would be something like this:
<?php
function better_ucwords($string) {
  $string = ucwords($string);
  $string = preg_replace('#[\\/][a-z]#e', "strtoupper('$0')", $string);
  return $string;
}
?>


joshuamallory

If you want to format a string like...
<?php
   $string = "computer programming/repair";
   print ucwords($string);
?>
Output: Computer Programming/repair
Notice the word after the slash (Programming/repair) isn't capitalized. To fix this, use CSS...
<?php
   $string = "computer programming/repair";
   print '<p style="text-transform:capitalize">';
   print ucwords($string);
   print '

';
?>


max

I have rewritten a UCSMART function adding a feature to translate special ASCII char (windows occidental ascii charset):
You can edit/add/delete char by use the first two string (be carefull to preserve the order of the string).
Enjoy!
<?
$ASCII_SPC_MIN = "àáâãäåæçèéêëìíîïðñòóôõöùúûüýÿžš";
$ASCII_SPC_MAX = "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝŸŽŠ";
function str2upper($text) {
global $ASCII_SPC_MIN,$ASCII_SPC_MAX;
return strtr(strtoupper($text),$ASCII_SPC_MIN,$ASCII_SPC_MAX);
}
function str2lower($text) {
global $ASCII_SPC_MIN,$ASCII_SPC_MAX;
return strtr(strtolower($text),$ASCII_SPC_MAX,$ASCII_SPC_MIN);
}
function ucsmart($text) {
global $ASCII_SPC_MIN;
return preg_replace(
'/([^a-z'.$ASCII_SPC_MIN.']|^)([a-z'.$ASCII_SPC_MIN.'])/e',
'"$1".str2upper("$2")',
str2lower($text)
);
}
?>
Massimiliano Cuttini


21-oct-2005 12:14

Here's a  piece that allows you to use the contents of a directory..  capitalizes the words and make links.. this particular example splits file names at _ and only selects file with .htm extensions (thought you could use any extension and call it using  include()  or soom such)
ie my_file_name.htm will produce
<a href="my_file_name.htm">My File Name</a>
<?php
$path = "/home/path/to/your/directory";
  $mydir = dir($path);
  while(($file = $mydir->read()) !== false) {
    if(substr($file, -4)=='.htm'){
$trans = array("_" => " ", ".htm" => ""); // creates the editing array
$newlist = strtr($file, $trans); // edits using editing array
echo "<a href=\"".$file."\">".ucwords($newlist)."</a>
";
}
   }
  ?>


gothicbunny

Here is a simple, yet winded, opposite to ucwords.
<?php
/*
# lcwords v1.000
# Convert the first word character to lowercase (opposite to ucwords)
# input string
# return string
*/
function lcwords($string)
{
/* Some temporary variables */
#loop variable
$a = 0;
#store all words in this array to be imploded and returned
$string_new = array();
#create array of all words
$string_exp = explode(" ",$string);
foreach($string_exp as $astring)
{
for($a=0;$a<strlen($astring);$a++)
{
#check that the character we are at {pos $a} is a word
#i.e. if the word was !A the code would fail at !
#then loop to the next character and succeed at A
#check at character position $a
if(preg_match("'\w'",$astring[$a]))
{
$astring[$a] = strtolower($astring[$a]);
#end the loop
break;
}
}
$string_new[] = $astring;
}
#recreate the string from array components using space deliminator
return implode(" ",$string_new);
}
?>
Of course a simplier way would be to use a callback, but I like working with long code :)


kendsnyder

Here is a function to capitalize a last name, accounting for hyphens, apostrophes, "Mc" and "Mac":
<?php
function CapitalizeLastName($name) {
   $name = strtolower($name);
   $name = join("'", array_map('ucwords', explode("'", $name)));
   $name = join("-", array_map('ucwords', explode("-", $name)));
   $name = join("Mac", array_map('ucwords', explode("Mac", $name)));
   $name = join("Mc", array_map('ucwords', explode("Mc", $name)));
   return $name;
}
?>
I speed tested it against functions that used preg_replace() with an "e" modifier, preg_replace_callback(), and a character-by-character parsing.  Unexpectedly, this function using join(), array_map() and explode() was fastest.


anton

for those, who not avoid regular expressions, solution of discussed problem:
$text=preg_replace('/(\W)(\w)/e', '"\\1".strtoupper("\\2")', ucfirst(strtolower($text)));


firewire

For those that want to capitalize based on a regular expression.
print preg_replace_callback('/(\s|^)[a-z]/', create_function('$a', 'return strtoupper($a[0]);'), 'hello this is my string');
This is a quick untested example.


babel - nospamplease - sympatico - ca

Correction to the code of firewire at itsyourdomain dot com:
preg_replace_callback('/\b(\w)(\w+)?/',
  create_function('$a',
  'return strtoupper($a[1]) . ((sizeof($a) > 2 ) ?  
      strtolower($a[2]) : "");'),
   'p.s.: hello.this is my string.');
Will work with punctuation as well as spaces.


27-aug-2002 03:20

Beware of language when using this function to collate personal names! This may not work with some languages and this depends on the current locale!
So it's best to simply use strtoupper() or strtolower(strtoupper()) to collate names for searches in a database. Avoid using strtolower() directly, as it won't collate some characters like the german 'ß' into 'ss'.
Capitalizing names is very language dependant: don't do it on address fields such as city names. Prefer uppercasing, or keep the original case if the string must be displayed to a user!


philip

Before noticing this function I made the following function (that does the same as ucwords):
<?php
function firstUpper($string)
{
$string = str_replace(array("Æ","Ø","Å"), array("æ","ø","å"), strtolower($string));
$ord = explode(" ", $string);

$return = "";
foreach ($ord as $val)
{
$return .= " " . str_replace(array("æ","ø","å"), array("Æ","Ø","Å"), strtoupper($val{0})) . substr($val,1,strlen($val)-1);
}
return $return;
}
?>
It also converts Danish letters without using the setlocale function.


mlong

An evolution of the previous (a little more compact I think):
$name="ReaLLY s'CREWED Name, JR.";
$break=1;
for ($i=0; $i < strlen($name); $i++)
{
$subed=substr($name,$i,1);
# if its a letter or num
if (((ord($subed) > 64) && (ord($subed) < 123)) ||
    ((ord($subed) > 48) && (ord($subed) < 58)))
{
 if ($break) { $newname .= strtoupper($subed); }
 else        { $newname .= strtolower($subed); }
 $break=0;
}
else
{
 # not a letter - a boundary
 $newname .= $subed;
 $break=1;
}
}
echo "$newname\n";


mistcat

Actually that code would work if you changed this line:
$words[0][] = $lastword;
to
$words[0][] = $lastword[0];


barnaby ritchley

A very easy way to convert to title case:
function titleCase($string)
    {
    return ucwords(strtolower($string));
    }
$myString = "SOME TEXT";
echo titleCase($myString);
//will print, "My Text"


deepdene

A function knowing about name case (i.e. caps on McDonald etc)
function name_case($name)
{
$newname = strtoupper($name[0]);
for ($i=1; $i < strlen($name); $i++)
{
$subed = substr($name, $i, 1);
if (((ord($subed) > 64) && (ord($subed) < 123)) ||
   ((ord($subed) > 48) && (ord($subed) < 58)))
{
$word_check = substr($name, $i - 2, 2);
if (!strcasecmp($word_check, 'Mc') || !strcasecmp($word_check, "O'"))
{
$newname .= strtoupper($subed);  
}
else if ($break)
{

$newname .= strtoupper($subed);
}
else      
{
$newname .= strtolower($subed);
}
$break=0;
}
else
{
// not a letter - a boundary
$newname .= $subed;
$break=1;
}
}
return $newname;
}


static bit

// programming/repair -> Programming/Repair
// mcdonald    o'neil   -> McDonand O'Neil
// art    of street        -> Art of Street
function NomeProprio($nome)
  {
  //two space to one
  $nome = str_replace("  ", " ", $nome);
  $nome = str_replace("  ", " ", $nome);
  $nome = str_replace("  ", " ", $nome);
  $intervalo = 1;
  for ($i=0; $i < strlen($nome); $i++)
      {
      $letra = substr($nome,$i,1);
      if (((ord($letra) > 64) && (ord($letra) < 123)) || ((ord($letra) > 48) && (ord($letra) < 58)))
         {
         $checa_palavra = substr($nome, $i - 2, 2);
         if (!strcasecmp($checa_palavra, 'Mc') || !strcasecmp($checa_palavra, "O'"))
            {
            $novonome .= strtoupper($letra);
            }
           elseif ($intervalo)
            {
            $novonome .= strtoupper($letra);
            }
           else
            {
            $novonome .= strtolower($letra);
            }
         $intervalo=0;
         }
        else
         {
         $novonome .= $letra;
         $intervalo = 1;
         }
      }
  $novonome = str_replace(" Of ", " of ", $novonome);
  $novonome = str_replace(" Da ", " da ", $novonome);
  $novonome = str_replace(" De ", " de ", $novonome);
  $novonome = str_replace(" Do ", " do ", $novonome);
  $novonome = str_replace(" E " , " e " , $novonome);
  return $novonome;
  }


24-dec-2005 03:34

"ieure at php dot net", your idea is pure poetry!
The function below will standardize the capitalization on people's names and the titles of reports and essays . You may need to adapt the lists in "$all_uppercase" and "$all_lowercase" to suit the data that you are working with.
function my_ucwords($str, $is_name=false) {
  // exceptions to standard case conversion
  if ($is_name) {
      $all_uppercase = '';
      $all_lowercase = 'De La|De Las|Der|Van De|Van Der|Vit De|Von|Or|And';
  } else {
      // addresses, essay titles ... and anything else
      $all_uppercase = 'Po|Rr|Se|Sw|Ne|Nw';
      $all_lowercase = 'A|And|As|By|In|Of|Or|To';
  }
  $prefixes = 'Mc';
  $suffixes = "'S";
  // captialize all first letters
  $str = preg_replace('/\\b(\\w)/e', 'strtoupper("$1")', strtolower(trim($str)));
  if ($all_uppercase) {
      // capitalize acronymns and initialisms e.g. PHP
      $str = preg_replace("/\\b($all_uppercase)\\b/e", 'strtoupper("$1")', $str);
  }
  if ($all_lowercase) {
      // decapitalize short words e.g. and
      if ($is_name) {
          // all occurences will be changed to lowercase
          $str = preg_replace("/\\b($all_lowercase)\\b/e", 'strtolower("$1")', $str);
      } else {
          // first and last word will not be changed to lower case (i.e. titles)
          $str = preg_replace("/(?<=\\W)($all_lowercase)(?=\\W)/e", 'strtolower("$1")', $str);
      }
  }
  if ($prefixes) {
      // capitalize letter after certain name prefixes e.g 'Mc'
      $str = preg_replace("/\\b($prefixes)(\\w)/e", '"$1".strtoupper("$2")', $str);
  }
  if ($suffixes) {
      // decapitalize certain word suffixes e.g. 's
      $str = preg_replace("/(\\w)($suffixes)\\b/e", '"$1".strtolower("$2")', $str);
  }
  return $str;
}
// A name example
print my_ucwords("MARIE-LOU VAN DER PLANCK-ST.JOHN", true);
// Output: Marie-Lou van der Planc-St.John
// A title example
print my_ucwords("to be or not to be");
// Output: "To Be or Not to Be"


Change Language


Follow Navioo On Twitter
addcslashes
addslashes
bin2hex
chop
chr
chunk_split
convert_cyr_string
convert_uudecode
convert_uuencode
count_chars
crc32
crypt
echo
explode
fprintf
get_html_translation_table
hebrev
hebrevc
html_entity_decode
htmlentities
htmlspecialchars_decode
htmlspecialchars
implode
join
levenshtein
localeconv
ltrim
md5_file
md5
metaphone
money_format
nl_langinfo
nl2br
number_format
ord
parse_str
print
printf
quoted_printable_decode
quotemeta
rtrim
setlocale
sha1_file
sha1
similar_text
soundex
sprintf
sscanf
str_getcsv
str_ireplace
str_pad
str_repeat
str_replace
str_rot13
str_shuffle
str_split
str_word_count
strcasecmp
strchr
strcmp
strcoll
strcspn
strip_tags
stripcslashes
stripos
stripslashes
stristr
strlen
strnatcasecmp
strnatcmp
strncasecmp
strncmp
strpbrk
strpos
strrchr
strrev
strripos
strrpos
strspn
strstr
strtok
strtolower
strtoupper
strtr
substr_compare
substr_count
substr_replace
substr
trim
ucfirst
ucwords
vfprintf
vprintf
vsprintf
wordwrap
eXTReMe Tracker