按 lower/upper 分解姓氏和名称

Explode surname and name by lower/upper

如何将名字和姓氏与这样的字符串分开:

Pietro DE GIOVANNI

Pietro 是名字,DE GIOVANNI 是姓氏)

我曾经在空格上用 explode() 来做到这一点,但显然它对这样的人不起作用。

提前致谢。

您可以像以前一样按空格分解名称,然后将结果作为名称的各个部分循环。检查 ctype_upper() 字符串是否纯大写,并将其附加到适当的变量。

放到一个函数中,可能是这样的

function split_name($fullname) {
    $firstname = "";
    $surname = "";

    $pieces = explode(" ", $fullname);
    foreach ($pieces as $name) {
        if (ctype_upper($name))
            $surname .= $name." ";
        else
            $firstname .= $name. " ";
    }
    return array("firstname" => $firstname, "surname" => $surname);
}

然后您就可以这样使用它了

$name = "Pietro DE GIOVANNI";
$split = split_name($name);
echo "Firstname: ".$split['firstname']."\nSurname: ".$split['surname'];

备注
这不适用于 James O'RILEYJohn-Paul JOHNSONJohn. F. KENNEDY 等名称。前两个我们可以通过在与 ctype_upper() 比较之前去除任何不是 a-zA-Z 的字符来规避,但后者我们将无法区分它是名字还是姓氏 - 没有足够的数据来不管怎样说。你可以假设它总是名字的一部分(例如),and/or检查它是否在我们开始查看姓氏之后(如果名字是大写字母尚未发现)。您可以通过检查

来处理前两种情况
if (ctype_upper(filter_var(str_replace("'", "", $name), FILTER_SANITIZE_STRING)))

而不是在原始代码块中使用 if 语句。这将删除引号和任何非 a-zA-Z 值。

这是一个 live demo,其中我删除了包含 a-zA-Z 旁边任何字符的名称,这将解释前两个问题。