Upper case

Any idea to change the code below in order to have this?
(single word)
abc => Abc … working

(one or two chars in the middle of the words, small case)
abcd xe efg hij => Abcd xe Efg Hij … not working
abcd x efg => Abcd x Efg … not working

(one or two chars in beginning or end, upper case)
ab cde => Ab Cde … working
abc de => Abc De … working
a bc => A Bc … working

(if it has a point)
ab.cd => Ab.cd

(other char)
abc - de => Abc - De

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;
}

The ucwords function alone seems to do what you want to do. If you feed it ‘abcd xe efg hij,’ it will return ‘Abcd Xe Efg Hij.’

Sorry about the exposition in the first post not very clear.

I need a function which converts uppercase the first letter of the word, except when its length is less than 3 chars.

Example:
echo function(‘abcd xe efg hij’); //Abcd xe Efg Hij
echo function(‘aBcd X efg’); //Abcd x Efg

May be trying to improve this will solve. adding something to the delimiter array

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;
}

Any ideas? Many thanks.

Perhaps not the most elegant, but it works. :slight_smile:

<?php
function ucspecial ($string) {
  $arr = explode (' ', $string);
  $arr2 = Array();
  $cnt = 0;
  foreach ($arr as $val) {
    if (strlen ($val) > 2 || $cnt == 0) {
      $arr2[] = ucfirst($val);
    } elseif ($cnt > 0 && $arr[$cnt-1] == '-'){
	  $arr2[] = ucfirst($val);
	} else {
      $arr2[] = $val;
    }
    $cnt++;
  }
  $string = implode (' ', $arr2);
  return $string;
}
echo ucspecial ('abcd xe efg hij') . '<br>';
echo ucspecial ('ab cde') . '<br>';
echo ucspecial ('ab.cd') . '<br>';
echo ucspecial ('abc - de') . '<br>';
?>

Above examples return the following:

Abcd xe Efg Hij
Ab Cde
Ab.cd
Abc - De

<?php
function ucname($name){
  $parts = explode(' ', strtolower($name));
  foreach($parts as & $part){
    if(2 <= strlen($part)){
      $part = ucfirst($part);
    }
  }
  return implode(' ', $parts);
}

$names = array(
  'Anthony sterling',
  'abcd xe efg hij',
  'ABcd X efg'
);

print_r(
  array_map(
    'ucname',
    $names
  )
);

/*
  Array
  (
      [0] => Anthony Sterling
      [1] => Abcd Xe Efg Hij
      [2] => Abcd x Efg
  )
*/

If the delimiter could be a range of characters, it maybe worth investigating preg_split.

Ah, I didn’t see the other requirements, thanks Ian.


<?php
function ucname($name){
  
  $parts = preg_split('~([\\s.-])~', strtolower($name), -1, PREG_SPLIT_DELIM_CAPTURE);
  
  foreach($parts as $index => & $part){
    
    $isFirst      = 0 === $index;
    $isLast       = count($parts) - 1 === $index;
    $isLongEnough = 2 < strlen($part);
    
    if($isFirst OR $isLast OR $isLongEnough){
      $part = ucfirst($part);
    }
    
  }
  return implode(null, $parts);
}

$names = array(
  'Anthony sterling',
  'abcd xe efg hij',
  'ABcd.X.efg',
  'fo - chi - chan - s'
);

print_r(
  array_map(
    'ucname',
    $names
  )
);

/*
  Array
  (
      [0] => Anthony Sterling
      [1] => Abcd xe Efg Hij
      [2] => Abcd.x.Efg
      [3] => Fo - Chi - Chan - S
  )
*/
?>

Many thanks for attention and support!!!
With your help it was easier…