62

我正在开发一个私人消息系统,允许用户按全名搜索用户,例如:“乔治华盛顿”。

我有两个名为$firstnameand$lastname的变量,搜索功能按相关性排序结果(您向该人发送了多少次消息)。如何获得将“乔治华盛顿”拆分为$firstname="George"和的文本字段$lastname="Washington"

4

17 回答 17

125

最简单的方法是使用explode:

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

获得零件后,将最后一个弹出为$lastname

$lastname = array_pop($parts);

最后,将数组的其余部分内爆为您的$firstname

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

例子:

$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";

结果:

tomatech:~ ariefbayu$ php ~/Documents/temp/test.php 
Lastname: ddd
Firstname: aaa bbb ccc
于 2012-11-30T01:03:21.630 回答
85

我喜欢cballou 的回答,因为努力检查是否只有名字。我想我会为其他来找我的人添加我的功能。

简单函数,使用正则表达式(单词字符和连字符)

  • 它假设姓氏将是一个单词。
  • 不对中间名做任何假设,所有都只是被分组为名字。
  • 你可以再次使用它,在“名字”结果上得到第一个和中间。

这是代码:

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

例 1:split_name('Angeler')输出:

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

例 2:split_name('Angeler Mcgee')输出:

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

例 3:split_name('Angeler Sherlee Mcgee')输出:

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

要拆分名字和中间名,

例 4:split_name('Angeler Sherlee')输出:

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

另一个功能 - 也检测中间名

后来我决定如果可以的话,自动计算出中间名会很好,所以我写了这个函数。

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

例 1:split_name('Angeler Sherlee Mcgee')输出:

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

例 2:split_name('Angeler Mcgee')输出:

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

另一种方式 - 无正则表达式

决定添加另一种不使用正则表达式的方式。

它还具有return false;不可识别的名称(null、空字符串、太多词组无法推断)。

<?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'));

输出

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
于 2015-07-10T00:00:38.250 回答
28

如果你有两个字的输入,你可以使用list()

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

无论如何你可以使用explode()

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

$firstname = $words[0];
$lastname = $words[1];
$third_word = $words[2];
// ..
于 2012-11-30T00:23:35.457 回答
17

在我的情况下,我只需要一种简单的方法来获得第一个和最后一个,但要考虑基本的中间名:

$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 . '.';

输出:

第一:比利,最后:约翰逊,中间:鲍比。

于 2013-04-11T20:22:21.083 回答
10
list($firstname, $lastname) = explode(' ', $fullname,2);
于 2015-04-03T09:44:06.227 回答
6

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

$string = "George Washington";
$name = explode(" ", $string);
echo $name[0]; // George 
echo $name[1]; // Washington
于 2012-11-30T00:22:13.897 回答
6

这是一个带有一些边界检查的答案。

虽然上面的答案是正确的,但它们没有提供任何形式的边界条件检查来确保您实际上有一个有效的名称开头。您可以通过strpos()检查是否存在空间来解决此问题。这是一个更彻底的例子:

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

值得注意的是,这假设姓氏是一个单词,而名字可以是任意组合。对于相反的效果,array_pop()换成array_shift().

于 2015-03-06T20:34:09.920 回答
4
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";

会导致:

first name: Johann Sebastian  
last name: Bach
于 2016-08-23T22:26:53.957 回答
3

所以我的用例是根据未经训练的用户输入来提取医生的姓名。所以我写了这个函数来检测最后一个逗号优先的场景以及我可能遇到的各种标题和后缀。

假设

  • 它可能需要一些微调,因为它还没有经过 beta 测试。我会尽量记住在修补功能时更新这篇文章。
  • 需要为每个用例定制前缀/后缀列表,因为综合列表实际上会损害功能。(例如“Mrs. Bishop”或“Dr. Ma”为空)
  • 也只提取中间名,忽略第一次遇到的中间名。

代码

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

输出

在此处输入图像描述

于 2019-04-30T16:22:56.897 回答
1

如果您不需要中间名,这是一个简单的解决方案:

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

只有一个名字:

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

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

于 2020-07-23T07:37:46.537 回答
1

我还没有看到这个提议:

在我的例子中,我需要将一个名字分成两个字段,第一个和最后一个,不管这个人有多少个名字。所以我做了以下事情:

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

这导致 $firstname = "Paul Thomas" 和 $lastname = "Anderson"

“end()”命令只是从分解的名称中获取最后一个数组元素,然后“str_replace”从全名中删除最后一个名称。

于 2021-01-26T22:47:15.283 回答
0

我用这个,它甚至用and,&和/等来分割名字,那里有多个名字

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

样本输出 Hanna 和 Mykhoylo Ilyashevych

Array

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

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

)

于 2018-09-23T18:00:12.587 回答
0

我发现这更好地满足了我的需求。它将第一个单词作为名字,并将其余单词作为姓氏。

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);
}
于 2018-09-30T10:23:38.810 回答
0

这是将全名拆分为名字和姓氏的一种非常简单的方法

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

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

带有中间名

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

$lastname = strstr($name, ' ');
echo trim($lastname); // Output: Sherlee Mcgee
于 2019-06-07T07:17:23.280 回答
0

无需太多工作即可获得包含 2 个元素的数组:

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 1parse_name("Johnny Deep");输出:

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

Ex 2parse_name("Lincoln Johnny Deep");输出:

array(
  0 => "Lincoln Johnny",
  1 => "Deep"
);
于 2020-01-06T09:16:36.973 回答
0

一行代码可以像

return (explode(" ", $yourName))[0];
于 2020-02-11T20:35:54.603 回答
-1

这将忽略中间,只得到第一个和最后一个。

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;
}
于 2018-02-07T17:58:57.647 回答