Split text string into $first and $last name in php

Php

Php Problem Overview


I'm developing a private message system that allows users to search for a user by their full name, e.g.: "George Washington".

I have two variables named $firstname and $lastname, and the search function orders results by relevancy (how many times you have messaged that person). How do I get a text field to split "George Washington" into $firstname="George" and $lastname="Washington"?

Php Solutions


Solution 1 - Php

The simplest way is, by using explode:

$parts = explode(" ", $name);

After you have the parts, pop the last one as $lastname:

$lastname = array_pop($parts);

Finally, implode back the rest of the array as your $firstname:

$firstname = implode(" ", $parts);

example:

$name = "aaa bbb ccc ddd";

$parts = explode(" ", $name);
if(count($parts) > 1) {
    $lastname = array_pop($parts);
    $firstname = implode(" ", $parts);
}
else
{
    $firstname = $name;
    $lastname = " ";
}

echo "Lastname: $lastname\n";
echo "Firstname: $firstname\n";

Would result:

tomatech:~ ariefbayu$ php ~/Documents/temp/test.php 
Lastname: ddd
Firstname: aaa bbb ccc

Solution 2 - Php

I like cballou's answer because there's an effort to check if there's only a first name. I thought I'd add my functions for anyone else who comes lookin'.

Simple Function, Using Regex (word char and hyphens)
  • It makes the assumption the last name will be a single word.
  • Makes no assumption about middle names, that all just gets grouped into first name.
  • You could use it again, on the "first name" result to get the first and middle though.

Here's the code:

// uses regex that accepts any word character or hyphen in last name
function split_name($name) {
    $name = trim($name);
    $last_name = (strpos($name, ' ') === false) ? '' : preg_replace('#.*\s([\w-]*)$#', '$1', $name);
    $first_name = trim( preg_replace('#'.preg_quote($last_name,'#').'#', '', $name ) );
    return array($first_name, $last_name);
}

Ex 1: split_name('Angeler') outputs:

array(
    0 => 'Angeler',
    1 => ''
);

Ex 2: split_name('Angeler Mcgee') outputs:

array(
    0 => 'Angeler',
    1 => 'Mcgee'
);

Ex 3: split_name('Angeler Sherlee Mcgee') outputs:

array(
    0 => 'Angeler Sherlee',
    1 => 'Mcgee'
);

To get the first and middle name split,

Ex 4: split_name('Angeler Sherlee') outputs:

array(
    0 => 'Angeler',
    1 => 'Sherlee'
);

Another Function - Detects Middle Names Too

Later I decided that it would be nice to have the middle name figured out automatically, if applicable, so I wrote this function.

function split_name($name) {
    $parts = array();

    while ( strlen( trim($name)) > 0 ) {
        $name = trim($name);
        $string = preg_replace('#.*\s([\w-]*)$#', '$1', $name);
        $parts[] = $string;
        $name = trim( preg_replace('#'.preg_quote($string,'#').'#', '', $name ) );
    }

    if (empty($parts)) {
        return false;
    }

    $parts = array_reverse($parts);
    $name = array();
    $name['first_name'] = $parts[0];
    $name['middle_name'] = (isset($parts[2])) ? $parts[1] : '';
    $name['last_name'] = (isset($parts[2])) ? $parts[2] : ( isset($parts[1]) ? $parts[1] : '');
    
    return $name;
}

Ex 1: split_name('Angeler Sherlee Mcgee') outputs:

array(
    'first_name' => 'Angeler',
    'middle_name' => 'Sherlee',
    'last_name' => 'Mcgee'
);

Ex 2: split_name('Angeler Mcgee') outputs:

array(
    'first_name' => 'Angeler',
    'middle_name' => '',
    'last_name' => 'Mcgee'
);

Another Way - Sans Regex

Decided to add another way that doesn't use regex.

It also has return false; for non-recognizable names (null, empty string, too many word groups to infer).

<?php

function split_name($string) {
    $arr = explode(' ', $string);
    $num = count($arr);
    $first_name = $middle_name = $last_name = null;
    
    if ($num == 2) {
        list($first_name, $last_name) = $arr;
    } else {
        list($first_name, $middle_name, $last_name) = $arr;
    }

    return (empty($first_name) || $num > 3) ? false : compact(
        'first_name', 'middle_name', 'last_name'
    );
}

var_dump(split_name('Angela Mcgee'));
var_dump(split_name('Angela Bob Mcgee'));
var_dump(split_name('Angela'));
var_dump(split_name(''));
var_dump(split_name(null));
var_dump(split_name('Too Many Names In Here'));

Outputs

Array
(
    [first_name] => Angela
    [middle_name] => NULL
    [last_name] => Mcgee
)

Array
(
    [first_name] => Angela
    [middle_name] => Bob
    [last_name] => Mcgee
)

Array
(
    [first_name] => Angela
    [middle_name] => NULL
    [last_name] => NULL
)

false

false

false

Solution 3 - Php

if you have exactly 2-word input you can use list()

list($firstname, $lastname) = explode(" ", $string);

anyway you can use explode()

$words = explode(" ", $string);

$firstname = $words[0];
$lastname = $words[1];
$third_word = $words[2];
// ..

Solution 4 - Php

In my situation, I just needed a simple way to get first and last, but account for basic middle names:

$parts = explode(' ', 'Billy Bobby Johnson'); // $meta->post_title
$name_first = array_shift($parts);
$name_last = array_pop($parts);
$name_middle = trim(implode(' ', $parts));

echo 'First: ' . $name_first . ', ';
echo 'Last: ' . $name_last . ', ';
echo 'Middle: ' . $name_middle . '.';

Output:

> First: Billy, Last: Johnson, Middle: Bobby.

Solution 5 - Php

list($firstname, $lastname) = explode(' ', $fullname,2);

Solution 6 - Php

http://php.net/manual/en/function.explode.php

$string = "George Washington";
$name = explode(" ", $string);
echo $name[0]; // George 
echo $name[1]; // Washington

Solution 7 - Php

Here's an answer with some bounds checking.

While the answers above are correct, they don't provide any form of bounds condition checks to ensure you actually have a valid name to begin with. You could go about this with a strpos() check to see if a space exists. Here's a more thorough example:

function split_name($name)
{
    $name = trim($name);
    if (strpos($name, ' ') === false) {
        // you can return the firstname with no last name
        return array('firstname' => $name, 'lastname' => '');

        // or you could also throw an exception
        throw Exception('Invalid name specified.');
    }

    $parts     = explode(" ", $name);
    $lastname  = array_pop($parts);
    $firstname = implode(" ", $parts);

    return array('firstname' => $firstname, 'lastname' => $lastname);
}

It's worth noting that this assumes the lastname is a single word whereas the firstname can be any combination. For the opposite effect, swap out array_pop() for array_shift().

Solution 8 - Php

function getFirstName($name) {
    return implode(' ', array_slice(explode(' ', $name), 0, -1));
}

function getLastName($name) {
    return array_slice(explode(' ', $name), -1)[0];
}

$name = 'Johann Sebastian Bach';
$firstName = getFirstName($name);
$lastName = getLastName($name);

echo "first name: $firstName\n";
echo "last name: $lastName\n";

Would result into:

first name: Johann Sebastian  
last name: Bach

Solution 9 - Php

So my use case was to extract the name of a doctor based on an untrained users input. So I wrote this function to detect the last-comma-first scenario and various titles and suffixes that I may encounter.

Assumptions

  • It will probably require some fine tuning as this has not been beta tested yet. I will try to remember to update this post as I patch the function.
  • The prefix/suffix list will need to be customized for each use case as a comprehensive list would actually be detrimental to functionality. (e.g. A "Mrs. Bishop" or "Dr. Ma" would be empty)
  • Also only middle initial is pulled and the middle names beyond the first encountered are ignored.

Code

function extractName($name)
{
  // Common/expected prefixes.
  $prefix_list = array(
    'mr',
    'mrs',
    'miss',
    'ms',
    'dr',
    'doctor',
  );

  // Common/expected suffixes.
  $suffix_list = array(
    'md',
    'phd',
    'jr',
    'sr',
    'III',
  );

  $parts = explode(' ', $name);

  // Grab the first name in the string.
  do
  {
    $first_name = array_shift($parts);
  } while ($first_name && in_array(str_replace('.', '', strtolower($first_name)), $prefix_list));

  // If the first name ends with a comma it is actually the last name. Adjust.
  if (strpos($first_name, ',') === (strlen($first_name) - 1))
  {
    $last_name = substr($first_name, 0, strlen($first_name) - 1);
    $first_name = array_shift($parts);

    // Only want the middle initial so grab the next text in the array.
    $middle_name = array_shift($parts);

    // If the text is a suffix clear the middle name.
    if (in_array(str_replace('.', '', strtolower($middle_name)), $suffix_list))
    {
      $middle_name = '';
    }
  }
  else
  {
    // Retrieve the last name if not the leading value.
    do
    {
      $last_name = array_pop($parts);
    } while ($last_name && in_array(str_replace('.', '', strtolower($last_name)), $suffix_list));

    // Only want the middle initial so grab the next text in the array.
    $middle_name = array_pop($parts);
  }


  return array($first_name, $last_name, substr($middle_name, 0, 1));
}

Output

enter image description here

Solution 10 - Php

This is simple solution if you don`t need middle name:

$name = "John Doe";
$name = trim($username);
$firstName = strtok($name, " "); // John
$lastName = strtok(" "); // Doe

Only one name:

$name = "John";
$name = trim($username);
$firstName = strtok($name, " "); // John
$lastName = strtok(" "); // False

https://www.php.net/manual/en/function.strtok.php

Solution 11 - Php

I have not seen this proposed:

In my case, I needed to split a name into two fields, first and last, regardless of how many names the person had. So I did the following:

$fullName = "Paul Thomas Anderson";
$lastname = end(explode(" ", $fullName));
$firstname = str_replace($lastname,'',$fullName);

This results in $firstname = "Paul Thomas" and $lastname = "Anderson"

The "end()" command just gets the last array element from the exploded name, and then the "str_replace" removes the last name from the full name.

Solution 12 - Php

I use this, it even splits names with and, & and / etc where multiple names are there

function getNames($namestrs){
	
	$allnames= array();
	$namestrs = trim($namestrs);
	$namestrs = str_replace(array(',',' and ',' & ', '&amp;','/'),'|',$namestrs);
	
	$namestrs = explode('|',$namestrs);
	
	foreach($namestrs as $key=> $namestr){
		$namestr = explode(' ',trim($namestr) );

		if(count($namestr)==1 || (count($namestr)==2 && strlen(trim($namestr[1]) )<3)){ 
			$firstname = $namestr[0];
			if(isset( $namestr[1])){
			$middlename = $namestr[1];	
			}
			else{
			$middlename ='';	
			}
			$lastname='';
			$thenames = $namestrs; //print_r($thenames); //echo $key;
			$thenames = array_slice($thenames, $key+1, NULL, TRUE);  //print_r($thenames);
		
			foreach($thenames as $c=>$a){
				$a = explode(' ',trim($a) );// print_r(	$a);
				
					if(count($a)>1 && trim($lastname) ==''){
					$lastname = $a[count($a)-1];

				}					
			}
		}			
		else if(count($namestr)==2){
			$firstname = $namestr[0];
			$middlename = '';
			$lastname = $namestr[1];
		}
		else if(count($namestr)==3){
			$firstname = $namestr[0];
			$middlename = $namestr[1];
			$lastname = $namestr[2];
		}
		else if(count($namestr)>3){
			$firstname = $namestr[0];
			$middlename = $namestr[1];
			$lastname = str_replace(array( $firstname,$middlename ),"", implode(' ',$namestr));
			$lastname = trim($lastname);
		}
		
		if($lastname=='3rd')	{
		$lastname = trim($middlename) ." "	.trim($lastname) ;
		$middlename ='';
		}		
		
		$allnames[] = array('firstname'=>$firstname,'middlename'=>$middlename,'lastname'=>$lastname );
	}
	
	return $allnames;
}

Sample output Hanna and Mykhoylo Ilyashevych

Array

( [0] => Array ( [firstname] => Hanna [middlename] => [lastname] => Ilyashevych )

[1] => Array
    (
        [firstname] => Mykhoylo
        [middlename] => 
        [lastname] => Ilyashevych
    )

)

Solution 13 - Php

I found this served my needs better. It takes the first word as the first name and lumps the rest as the last name.

function splitName($name) {
    $name = trim($name);
    $name = explode(' ', $name);
    $first_name = $name[0];
    unset($name[0]);
    $last_name = implode(' ', $name);
    return array($first_name, $last_name);
}

Solution 14 - Php

Here is a very simple way to split full name into first name and last name

$name = "John Smith";
$firstname = strtok($name, ' ');
echo trim($firstname); // Output: John

$lastname = strstr($name, ' ');
echo trim($lastname); // Output: Smith

With Middle Name

$name = "Angeler Sherlee Mcgee";
$firstname = strtok($name, ' ');
echo trim($firstname); // Output: Angeler

$lastname = strstr($name, ' ');
echo trim($lastname); // Output: Sherlee Mcgee

Solution 15 - Php

No need too much work just to get an array with 2 elements:

function parse_name($full_name) {
		$parts = explode(" ", $full_name);

		if (count($parts) > 2) {
			$last = array_pop($parts);
			return [implode(" ", $parts), $last];
		}

		return [$parts[0], $parts[1]];
}

Ex 1 parse_name("Johnny Deep"); outputs :

array(
  0 => "Johnny",
  1 => "Deep"
);

Ex 2 parse_name("Lincoln Johnny Deep"); outputs :

array(
  0 => "Lincoln Johnny",
  1 => "Deep"
);

Solution 16 - Php

One line code can be like

return (explode(" ", $yourName))[0];

Solution 17 - Php

This will ignore the middle and just get the first and last.

function split_name($name) {		
	$parts = explode(" ", $name);
	$lastname = array_pop($parts);
	while(count($parts) > 1)
	{
		array_pop($parts);
	}
	$firstname = implode(" ", $parts);
	
	$name = array(
			'first_name' => $firstname,
			'last_name' => $lastname,
	);
	
	return $name;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncentreeView Question on Stackoverflow
Solution 1 - PhpariefbayuView Answer on Stackoverflow
Solution 2 - PhpamurrellView Answer on Stackoverflow
Solution 3 - PhpmychalvlcekView Answer on Stackoverflow
Solution 4 - PhpmhulseView Answer on Stackoverflow
Solution 5 - PhpSultanView Answer on Stackoverflow
Solution 6 - PhpAlvarezView Answer on Stackoverflow
Solution 7 - PhpCorey BallouView Answer on Stackoverflow
Solution 8 - PhpNik SumeikoView Answer on Stackoverflow
Solution 9 - Phpdanielson317View Answer on Stackoverflow
Solution 10 - PhpLakyView Answer on Stackoverflow
Solution 11 - PhpDavid EdwardsView Answer on Stackoverflow
Solution 12 - PhpAnupam RekhaView Answer on Stackoverflow
Solution 13 - PhpLaithView Answer on Stackoverflow
Solution 14 - PhpAjay PatidarView Answer on Stackoverflow
Solution 15 - PhpspetsnazView Answer on Stackoverflow
Solution 16 - PhpBurhan IbrahimiView Answer on Stackoverflow
Solution 17 - PhpS.Y.View Answer on Stackoverflow