有人知道一个优雅的功能来修复名称案件?

时间:2012-10-17 06:30:29

标签: php

幼儿园101告诉我们一些人:“你名字中的字母应该是小写的,大写的第一个字母。”然而在这个后文化时代,人们如何在网络形式中输入他们的名字似乎取决于他们的心情,或者太阳耀斑或诸如此类的东西:全部大写,全部小写,混合,颠倒......

哲学上,我说什么!占据你的名字,谁在乎。但我有OCD客户端,他们更喜欢看到数据标准化,标准化,可预测。所以我问你们,如果你看到任何经过深思熟虑的PHP函数用于修复案例名称,那么考虑到ucwords()完全屠宰的各种例外情况,例如:

  • Sven-Alex Crumpet
  • 罗纳尔多麦克多纳多
  • Boopsie O'Brien
  • J.R。鲍勃·多布斯
  • Francesca de los Gatos
  • YungCheng Li

那些试图容纳这些字母反叛者的任何功能?

更新
从Robin v.G.的van-tage来看,没有任何脚本可以统治它们。但是我已经确定完全以小写或大写形式输入的名字可能是一个很好的擦洗的候选人。所以对于这些,我会做...

    if ($name == strtoupper($name) || $name == strtolower($name)) {
        $name = ucwords(strtolower($name));
    }

修改这个以修复一些可能的例外很容易:破折号,撇号,'McD'等。将会出现错误,但谁会抱怨?不是那个以小写字母输入他们名字的温柔的混蛋。

哦等等,我的名字是小写的......

4 个答案:

答案 0 :(得分:8)

这根本不可能。

姓名拼写因国家/地区而异,正如您在问题中所示。最简单的方法是找到最常见的拼写方式,那就是将每个'单词'的每个首字母大写,即每个字符串前面都有空格,连字符,点或熵。

这并不能解决你所有的问题(YungCheng,McDonaldo),并且还会给你留下其他问题,但这就像你要得到的那么近。

比较

  • Alex Van Halen(美国拼写)
  • Alex van Halen(正确的荷兰语拼写)

没有算法解决这个问题。

This article很好地说明了荷兰名字的问题,而这只是一种语言。对于世界上的每种语言,可能都有这样的文章。 ;)

答案 1 :(得分:5)

这是一次尝试

$names=array();
$names[]="sven-alex crumpet";
$names[]="RONALDO McDonalDO";
$names[]="Boopsie o'Brien";
$names[]="j.r. BOB DOBBS";
$names[]="francesca DE LOS gatOS";
$names[]="yungcheng LI";
$names[]="mr hankey";
$names[]="santas little helper";
$names[]="j.r.r. tolkien";

$splitters=array(' ','.',"'",'-'); //more to come
$fixedNames=array();

foreach($names as $name) {
    $fixed='';
    $blank=str_replace($splitters,'?',$name);
    $n=explode('?',$blank);
    foreach($n as $f) $fixed.=ucfirst(strtolower($f)).' ';
    for ($i=0;$i<strlen($fixed);$i++) {
        if ($fixed[$i]==' ') {
            if ($blank[$i]=='?') {
                $fixed[$i]=$name[$i];
            }
        }
    }
    $fixedNames[]=substr_replace($fixed,'', -1);
}

echo '<pre>';
print_r($fixedNames);
echo '<pre>';

输出

Array
(
    [0] => Sven-Alex Crumpet
    [1] => Ronaldo Mcdonaldo
    [2] => Boopsie O'Brien
    [3] => J.R. Bob Dobbs
    [4] => Francesca De Los Gatos
    [5] => Yungcheng Li
    [6] => Mr Hankey
    [7] => Santas Little Helper
    [8] => J.R.R. Tolkien
)

如果没有算法处理区域/文化惯例和一个巨大的名称数据库来比较,就不可能“纠正”YungCheng这样的名称。

答案 2 :(得分:1)

但是,这是一个相当老的问题:

function titleCase($string, $delimiters = array(" ", "-", ".", "'", "O'", "Mc", "Mac"), $exceptions = array("and", "to", "of", "das", "dos", "de", "do", "da", "los", "von", "van", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X")) {
    /*
     * Exceptions in lower case are words you don't want converted
     * Exceptions all in upper case are any words you don't want converted to title case
     *   but should be converted to upper case, e.g.:
     *   king henry viii or king henry Viii should be King Henry VIII
     */
    $string = mb_convert_case($string, MB_CASE_TITLE, "UTF-8");
    foreach ($delimiters as $dlnr => $delimiter) {
        $words = explode($delimiter, $string);
        $newwords = array();
        foreach ($words as $wordnr => $word) {
            if (in_array(mb_strtoupper($word, "UTF-8"), $exceptions)) {
                // check exceptions list for any words that should be in upper case
                $word = mb_strtoupper($word, "UTF-8");
            } else if (in_array(mb_strtolower($word, "UTF-8"), $exceptions)) {
                // check exceptions list for any words that should be in lower case
                $word = mb_strtolower($word, "UTF-8");
            } else if (!in_array($word, $exceptions)) {
                // convert to uppercase (non-utf8 only)
                $word = ucfirst($word);
            }
            array_push($newwords, $word);
        }
        $string = join($delimiter, $newwords);
    } //foreach
    return $string;
}

它对YungCheng无效,但几乎可以用于其他任何用途。唯一的问题是,如果$string仅是一个姓氏,例如“ do Carmo”,则它将返回“ Do Carmo”。它实际上是为全名构建的,因此如果您$string = "frederick do carmo";,它将返回“ Frederick do Carmo”。希望对您有所帮助。

答案 3 :(得分:-1)

我发现了一个像样的库来处理用python编写的不同格式的各种人名,称为nameparser。它仍然没有处理上面列出的所有名称,但是有些configuration你可能会接近。

我还写了一篇简短的blog来描述如何从终端获取nameparser库。也许它会对某人有所帮助。

这是基本的python脚本:

import sys
import json
from nameparser import HumanName

rawname = ' '.join(sys.argv[1:]).lower().strip()

name = HumanName(rawname)

# attempt to fix name title case
name.capitalize()

print json.dumps({
    'fullname': name.__str__(),
    'title': name.title,
    'first': name.first,
    'middle': name.middle,
    'last': name.last,
    'suffix': name.suffix,
    'nickname': name.nickname
})