blacksenator/name-parser

PHP 库,用于解析包含全名的字符串到各个部分

v1.2.12 2020-01-22 16:30 UTC

README

这是 THE ICONIC name parser 的增强版本,对德语特性进行了调整。

目的

它的目的是将包含全名、可能的称呼、首字母缩写、后缀等的单个字符串分割成有意义的部分,如名字、姓氏、首字母等。

它主要针对德语和英语名字,但只要使用拉丁字母拼写,效果都很好。

例如 Otto Eduard Leopold Fürst von Bismarck-Schönhausen 被解析为

  • 名字: Otto
  • 中间名: Eduard Leopold
  • 前缀: von
  • 姓氏: Bismarck-Schönhausen
  • 后缀: Fürst

特性

支持的格式

此解析器能够处理带逗号和不带逗号的名字模式。如果没有逗号,字符串首先与 公司名称标识符('GmbH'., 'Co. KG' 等)进行比较。如果是,则跳过解析,整个字符串将被标记为公司名称。

否则,假设一个人的名字遵循以下模式

... [firstname] ... [lastname] ...

... [lastname] ..., ... [firstname] ...

... [lastname] ..., ... [firstname] ..., [suffix]

海中捞针

用于搜索公司名称等特性的字符串可以在 ../src/Language 文件夹中找到。我添加了大约一百个字符串模式,这些模式可以用来识别公司(可能需要补充)。

支持的部分

  • 称呼(例如 Hr, Fr 等)
  • 名字
  • 中间名
  • 首字母(单个字母,可能后跟一个点)
  • 昵称(括号、方括号等内的部分)
  • 姓氏(也支持前缀,如 von, de 等)
  • 后缀(Jr, Senior 等)
  • 头衔(如 Dr. med., Dr.h.c. 等学术头衔)
  • 姓氏扩展(贵族称谓,如 Gräfin,Baron)

vCard 支持

您可以得到一个键匹配名称属性的数组 - 相对应于 RFC 6350

例如,Bismarck-Schönhausen, Otto Eduard Leopold Fürst von 转换为

[
'FN' => 'Otto Eduard Leopold Fürst von Bismarck-Schönhausen',
'N' => 'Bismarck-Schönhausen;Otto;Eduard,Leopold;;Fürst,von',
'NICKNAME' => '',
'ORG' => '',
]

但是,像 Fürstlich von Bismarck'sche Brennerei GmbH 这样的公司变为

[
'FN' => "Fürstlich von Bismarck'sche Brennerei GmbH",
'N' => '',
'NICKNAME' => '',
'ORG' => "Fürstlich von Bismarck'sche Brennerei GmbH",
]

其他特性

  • 称呼、后缀和姓氏前缀的多语言支持
  • 可自定义昵称分隔符
  • 可自定义所有输出字符串的规范化(原始值仍然可访问)
  • 可自定义空白字符

示例

可以在 解析器单元测试 中找到 60 多种不同的成功解析的名字模式。

设置

composer require blacksenator/name-parser

用法

基本用法

<?php

$parser = new blacksenator\NameParser\Parser();

$name = $parser->parse($input);

echo $name->getCompany();
echo $name->getSalutation();
echo $name->getFirstname();
echo $name->getLastname();
echo $name->getMiddlename();
echo $name->getNickname();
echo $name->getInitials();
echo $name->getSuffix();
echo $name->getTitle();
echo $name->getExtension();

print_r($name->getAll());

print_r($name->getVCardArray(true));

echo $name;

对于缺失的部分,返回一个空字符串。

特殊部分检索功能

显式姓氏部分

您可以使用以下方式分别检索姓氏前缀和纯姓氏

echo $name->getLastnamePrefix();
echo $name->getLastname(true); // true enables strict mode for pure lastnames, only

带规范化包裹的昵称

默认情况下,getNickname() 返回纯字符串形式的昵称。但是,您可以通过传递 true 来应用与 echo $name 中相同的规范化括号包裹。

echo $name->getNickname(); // Der Eiserne Kanzler
echo $name->getNickname(true); // (Der Eiserne Kanzler)

按输入顺序重新打印名字

您可以在保持通过 getGivenName() 应用规范化的同时,按输入顺序重新打印构成名字(即名字、中间名和任何首字母)的部分。

echo $name->getGivenName(); // Otto Eduard Leopold

重新打印全名(实际名字部分)

您可以通过getFullName()方法重新打印全名,即以上给出的名字,后面跟任何姓氏部分(不包括任何称呼、昵称或后缀)。

echo $name->getFullName();

设置语言

$parser = new blacksenator\NameParser\Parser([
    new blacksenator\NameParser\Language\German(),  // default in this version
    new blacksenator\NameParser\Language\English(), // recommended
      //
])

设置昵称分隔符

$parser = new blacksenator\NameParser\Parser();
$parser->setNicknameDelimiters(['(' => ')']);

设置空白字符

$parser = new blacksenator\NameParser\Parser();
$parser->setWhitespace("\t _.");

限制称呼的位置

$parser = new blacksenator\NameParser\Parser();
$parser->setMaxSalutationIndex(2);

这要求称呼必须出现在给定输入字符串的前两个单词中。默认值为输入字符串单词数的一半,这意味着称呼可能出现在姓氏部分的第一个一半。

调整组合首字母支持

$parser = new blacksenator\NameParser\Parser();
$parser->setMaxCombinedInitials(3);

组合首字母是几个大写字母的组合,例如DJJ.T.,中间没有空格。解析器将此类大写字母序列(可选的点)视为组合首字母,并将它们解析为单独的首字母。此值调整单个姓氏部分中可识别为组合首字母的最大大写字母数量。超过指定最大字母数量的部分将不会被解析为首字母,因此很可能会被解析为姓氏或中间名。

默认值是2。

要禁用组合首字母支持,将此值设置为1;

提示

提供干净的输入字符串

如果您的输入字符串除了名字和直接相关的内容(如称呼、后缀等)之外,还包括其他部分,那么这些额外的部分很容易让解析器混淆。因此,建议在将输入传递给解析器之前,先预处理任何非干净输入,以隔离名字。

多遍解析

我们尚未尝试过,但您可能可以通过连续进行几次解析来提高结果。例如。

$parser = new Parser();
$name = $parser->parse($input);
$name = $parser->parse((string) $name);
...

您甚至可以从前一次遍历的各个部分中组合新的输入字符串。

处理不同语言的名字

解析器版本主要基于德语和英语名字的格式,但尽量与其他语言的姓名兼容。在称呼、姓氏前缀、后缀等或在某些情况下甚至在解析顺序上可能出现问题。

为了正确解释姓名字符串,了解其来源非常重要:德国的“von”作为前缀不是姓氏“Bismark”的一部分。另一方面,荷兰的“van”或爱尔兰的“Mac”则是姓氏的一部分。

为了解决称呼、姓氏前缀和后缀的问题,您可以创建一个单独的语言定义文件,并在实例化解析器时注入它,请参阅上面的“设置语言”部分,并比较现有的语言文件作为示例。

撇号

当添加或编辑语言文件时,请考虑以下事项:仅使用撇号“ ' ”(U+0027)!在姓名中,所有类似撇号和印刷体撇号的字符都映射到U+0027,以消除拼写错误来源的错误。

解析顺序

为了处理解析顺序,您可能需要重新格式化输入字符串,例如通过简单地将它分割成单词并反转它们的顺序。您甚至可以让解析器在原始字符串和反转字符串上运行,然后从两个结果中的任一个选择最佳结果。例如,从其中一个中选择称呼,从另一个中选择姓氏。

语言检测

姓名解析器没有内置的语言检测功能。然而,您可能已经在表单中询问了用户的国籍。如果这样做,您可能希望将传递给解析器的语言定义文件缩小到给定语言,以及可能的备用语言如英语。您还可以使用此信息来准备上述概述的输入字符串。

此外,Patrick Schur 开发了一个 PHP 语言检测库,似乎能提供令人惊叹的结果。仅运行在姓名输入字符串上可能不会给你带来好运,但如果你有任何更多该人的实际语言文本,可以使用这个库来检测语言,然后再按照上述步骤操作。

性别检测

性别检测不在这个项目的范围内。从姓名中检测性别通常需要大量的名字到性别的映射列表。

然而,你可以使用这个解析器从输入字符串中提取称呼、名和昵称,然后使用这些信息通过另一个包(例如 这个包)或服务来实现性别检测。

在规范化中找乐子

编写不同语言的文件不仅可以用于解析,还可以将称呼、前缀和后缀的规范化版本重新映射,以将它们转换成完全不同的内容。

例如,你可以将 Ms. 映射为 王国的公主,然后按适当顺序输出这些部分,构建一个自动转换例如 Ms. Louisa LichtensteinLouisa,王国的公主,Lichtenstein 的管道。当然,这是一个愚蠢且相当牵强的例子,但你能理解其大意。

当然,这也可以以更有用的方式使用,例如将缩写头衔拼写成全称,如 Prof. 作为 教授 等。

许可证

这个分支和 THE ICONIC Name Parser PHP 库的源代码都是 MIT 许可证下发布的。