格式化人名 - PHP(或任何语言)库?

时间:2013-04-08 20:59:44

标签: php formatting string-formatting

有没有办法格式化人名?例如,“joHn dOE”应为“John Doe”。或者“angus macgyver”应该是“Angus MacGyver”。等

我知道任何解决方案可能都不会完整(名称规则太多了),但总比没有好。有什么建议吗?

3 个答案:

答案 0 :(得分:2)

我一直在寻找能够处理名称正确大写的php脚本。虽然我意识到处理100%的案件很困难

https://en.wikipedia.org/wiki/List_of_family_name_affixes

我认为这个脚本可以很好地处理95%的用例,至少对我们来说是这样。这当然是一个很好的起点。

http://www.media-division.com/correct-name-capitalization-in-php/

function titleCase($string) 
{
    $word_splitters = array(' ', '-', "O'", "L'", "D'", 'St.', 'Mc');
    $lowercase_exceptions = array('the', 'van', 'den', 'von', 'und', 'der', 'de', 'da', 'of', 'and', "l'", "d'");
    $uppercase_exceptions = array('III', 'IV', 'VI', 'VII', 'VIII', 'IX');

    $string = strtolower($string);
    foreach ($word_splitters as $delimiter)
    { 
        $words = explode($delimiter, $string); 
        $newwords = array(); 
        foreach ($words as $word)
        { 
            if (in_array(strtoupper($word), $uppercase_exceptions))
                $word = strtoupper($word);
            else
            if (!in_array($word, $lowercase_exceptions))
                $word = ucfirst($word); 

            $newwords[] = $word;
        }

        if (in_array(strtolower($delimiter), $lowercase_exceptions))
            $delimiter = strtolower($delimiter);

        $string = join($delimiter, $newwords); 
    } 
    return $string; 
}

答案 1 :(得分:1)

正如评论中已经建议的那样,在PHP中,你可以这样做:

$name_formatted = ucfirst(strtolower($name_unformatted));

这将处理90%的案件。然后我会把它放到一个函数中并添加规则来处理MacGuyver,O'Reilly类型异常。

<强>更新 正如所指出的,ucfirst仅执行字符串中的第一个单词。您可以使用正则表达式将每个单词中的所有首字母大写,或者执行如下函数:

<?php
$name_unformatted = "JOHN DOE";

function format_name($name_unformatted)
{
   $name_formatted = ucwords(strtolower($name_unformatted));  // this will handle 90% of the names

   // ucwords will work for most strings, but if you wanted to break out each word so you can deal with exceptions, you could do something like this:
   $separator = array(" ","-","+","'");
   foreach($separator as $s)
   {
      if (strpos($name_formatted, $s) !== false)
      {
         $word = explode($s, $name_formatted);
         $tmp_ary = array_map("ucfirst", array_map("strtolower", $word));  // whatever processing you want to do here
         $name_formatted = implode($s, $tmp_ary);
      }
   }

   return $name_formatted;
}

echo format_name($name_unformatted);
?>

您可以展开此功能来处理您的姓名例外。

答案 2 :(得分:0)

对于意大利人的名字,我找到了一个简单的解决方案

function formatName(string $firstName, string $lastName): array
{
    $delimiters = " -’'\t\r\n\f\v";

    return \array_map(
        fn ($string) => \ucwords(\mb_strtolower($string), $delimiters),
        [$firstName, $lastName]
    );
}

在我的情况下,我不得不处理D'AmicoDe AngelisDi CataldoRossi-Bianchi之类的姓氏,这种快速解决方案效果很好。

主要玩家是

\ucwords(\mb_strtolower($string), $delimiters)

剩下的只是我如何通过将名字和姓氏分开来处理名字的一部分。