在 php 中将文本字符串拆分为 $first 和 $last name

新手上路,请多包涵

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

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

原文由 centree 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 610
2 个回答

我喜欢 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

原文由 amurrell 发布,翻译遵循 CC BY-SA 4.0 许可协议

此功能适用于西班牙语名称,包括:名字、中间名、姓氏、母亲的姓氏和已婚姓氏(仅适用于女性)。这种名称格式在拉丁美洲非常普遍。

 public function split_name(string $name, array $words2join = [], array $remove_prefix = []): object
{
    $result = [];

    $name = strtolower(trim($name));
    $name = preg_replace('/\s+/', ' ', $name);

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

    $name = '';

    foreach($words as $word)
    {
        if (in_array($word, $words2join))
            $word .= '%';
        else
            $word .= ' ';

        $name .= $word;
    }

    $words = explode(' ', trim($name));

    $result['first_name'] = $words[0] ?? '';
    $result['middle_name'] = isset($words[3]) ? (isset($words[2]) ? $words[1] : '') : '';
    $result['last_name'] = isset($words[3]) ? ($words[2] ?? ($words[1] ?? '')) : $words[1] ?? '';
    $result['mother_last_name'] = $words[3] ?? ($words[2] ?? '');
    $result['married_last_name'] = $words[4] ?? '';

    foreach($result as $key => $value)
    {
        $value = ucwords(str_replace('%', ' ', $value));

        if (isset($remove_prefix[$key]))
        {
            $length = strlen($remove_prefix[$key]);

            if (substr($value, 0, $length))
                $value = substr($value, $length + 1, strlen($value));
        }

        $result[$key] = trim($value);
    }

    return (object) $result;
}

例子:

 $result = K7Text::split_name('Edgardo Hormelis Gomez Gaitan', ['del','de','la'], ['married_last_name' => 'de']);
print_r($result);

$result = K7Text::split_name('Miguel H. Pitty De León', ['del','de','la'], ['married_last_name' => 'de']);
print_r($result);

$result = K7Text::split_name('Santiago De La Cruz Abrego Abrego', ['del','de','la'], ['married_last_name' => 'de']);
print_r($result);

$result = K7Text::split_name('María González', ['del','de','la'], ['married_last_name' => 'de']);
print_r($result);

$result = K7Text::split_name('Lucibeth Del Carmen De La Rosa Palacio de Paredes', ['del','de','la'], ['married_last_name' => 'de']);
print_r($result);

会导致:


stdClass Object
(
    [first_name] => Edgardo
    [middle_name] => Hormelis
    [last_name] => Gomez
    [mother_last_name] => Gaitan
    [married_last_name] =>
)
stdClass Object
(
    [first_name] => Miguel
    [middle_name] => H.
    [last_name] => Pitty
    [mother_last_name] => De León
    [married_last_name] =>
)
stdClass Object
(
    [first_name] => Santiago
    [middle_name] => De La Cruz
    [last_name] => Abrego
    [mother_last_name] => Abrego
    [married_last_name] =>
)
stdClass Object
(
    [first_name] => María
    [middle_name] =>
    [last_name] => González
    [mother_last_name] =>
    [married_last_name] =>
)
stdClass Object
(
    [first_name] => Lucibeth
    [middle_name] => Del Carmen
    [last_name] => De La Rosa
    [mother_last_name] => Palacio
    [married_last_name] => Paredes
)

原文由 Ezequiel Villarreal 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题