The accepted answer doesn't work for languages other than english, or names such as "Oscar de la Hoya".
Here's something I did that I think is utf-8 safe and works for all of those cases, building on the accepted answer's assumption that a prefix and suffix will have a period:
/**
* splits single name string into salutation, first, last, suffix
*
* @param string $name
* @return array
*/
public static function doSplitName($name)
{
$results = array();
$r = explode(' ', $name);
$size = count($r);
//check first for period, assume salutation if so
if (mb_strpos($r[0], '.') === false)
{
$results['salutation'] = '';
$results['first'] = $r[0];
}
else
{
$results['salutation'] = $r[0];
$results['first'] = $r[1];
}
//check last for period, assume suffix if so
if (mb_strpos($r[$size - 1], '.') === false)
{
$results['suffix'] = '';
}
else
{
$results['suffix'] = $r[$size - 1];
}
//combine remains into last
$start = ($results['salutation']) ? 2 : 1;
$end = ($results['suffix']) ? $size - 2 : $size - 1;
$last = '';
for ($i = $start; $i <= $end; $i++)
{
$last .= ' '.$r[$i];
}
$results['last'] = trim($last);
return $results;
}
Here's the phpunit test:
public function testDoSplitName()
{
$array = array(
'FirstName LastName',
'Mr. First Last',
'First Last Jr.',
'Shaqueal O\'neal',
'D’angelo Hall',
'Václav Havel',
'Oscar De La Hoya',
'АБВГҐД ЂЃЕЀЁЄЖЗ', //cyrillic
'דִּיש מַחֲזֹור', //yiddish
);
$assertions = array(
array(
'salutation' => '',
'first' => 'FirstName',
'last' => 'LastName',
'suffix' => ''
),
array(
'salutation' => 'Mr.',
'first' => 'First',
'last' => 'Last',
'suffix' => ''
),
array(
'salutation' => '',
'first' => 'First',
'last' => 'Last',
'suffix' => 'Jr.'
),
array(
'salutation' => '',
'first' => 'Shaqueal',
'last' => 'O\'neal',
'suffix' => ''
),
array(
'salutation' => '',
'first' => 'D’angelo',
'last' => 'Hall',
'suffix' => ''
),
array(
'salutation' => '',
'first' => 'Václav',
'last' => 'Havel',
'suffix' => ''
),
array(
'salutation' => '',
'first' => 'Oscar',
'last' => 'De La Hoya',
'suffix' => ''
),
array(
'salutation' => '',
'first' => 'АБВГҐД',
'last' => 'ЂЃЕЀЁЄЖЗ',
'suffix' => ''
),
array(
'salutation' => '',
'first' => 'דִּיש',
'last' => 'מַחֲזֹור',
'suffix' => ''
),
);
foreach ($array as $key => $name)
{
$result = Customer::doSplitName($name);
$this->assertEquals($assertions[$key], $result);
}
}