有人有PHP功能来正确地将人名大写吗?

时间:2009-07-30 18:57:19

标签: php

我正在寻找一个能够正确地利用麦当劳,菲茨杰拉德,麦克阿瑟,奥伦尼,西奥德拉特等名字的功能。

有谁知道一个合理的工作?我猜测任何功能都不会支持所有可能性。

当然,单独的ucwords不起作用,因为它只是将每个单词的第一个字母大写。

编辑:我知道会出现问题,所有可能性都不会得到支持。但是现在的问题是我有一个大约有5万个名字的数据库,这些名字大多数都是全部大写的,所以在不引起拼写错误的情况下编辑每个名字会很麻烦。使用导致20%问题的脚本会快得多,并且会导致错误少得多。

4 个答案:

答案 0 :(得分:6)

也许你需要这样的东西ucwords function note

答案 1 :(得分:3)

你可能已经意识到了这一点,但是你要面对的一个巨大问题是,有些名称的“正确”大写不止一个 - 例如,在你的例子中,我不同意菲茨杰拉德的说法。

答案 2 :(得分:1)

我想到了这个

/**
  * Normalize the given (partial) name of a person.
  *
  * - re-capitalize, take last name inserts into account
  * - remove excess white spaces
  *
  * Snippet from: https://timvisee.com/blog/snippet-correctly-capitalize-names-in-php
  *
  * @param string $name The input name.
  * @return string The normalized name.
  */
function name_case($name) {
    // A list of properly cased parts
    $CASED = [
      "O'", "l'", "d'", 'St.', 'Mc', 'the', 'van', 'het', 'in', "'t", 'ten',
      'den', 'von', 'und', 'der', 'de', 'da', 'of', 'and', 'the', 'III', 'IV',
      'VI', 'VII', 'VIII', 'IX',
    ];

    // Trim whitespace sequences to one space, append space to properly chunk
    $name = preg_replace('/\s+/', ' ', $name) . ' ';

    // Break name up into parts split by name separators
    $parts = preg_split('/( |-|O\'|l\'|d\'|St\\.|Mc)/i', $name, -1, PREG_SPLIT_DELIM_CAPTURE);

    // Chunk parts, use $CASED or uppercase first, remove unfinished chunks
    $parts = array_chunk($parts, 2);
    $parts = array_filter($parts, function($part) {
            return sizeof($part) == 2;
        });
    $parts = array_map(function($part) use($CASED) {
            // Extract to name and separator part
            list($name, $separator) = $name;

            // Use specified case for separator if set
            $cased = current(array_filter($CASED, function($i) use($separator) {
                return strcasecmp($i, $separator) == 0;
            }));
            $separator = $cased ? $cased : $separator;

            // Choose specified part case, or uppercase first as default
            $cased = current(array_filter($CASED, function($i) use($name) {
                return strcasecmp($i, $name) == 0;
            }));
            return [$cased ? $cased : ucfirst(strtolower($name)), $separator];
        }, $parts);
    $parts = array_map(function($part) {
            return implode($part);
        }, $parts);
    $name = implode($parts);

    // Trim and return normalized name
    return trim($name);
}

它使用零件清单(假定外壳正确)。它将永远不会是完美的,但是它可能会改善您的实现。

答案 3 :(得分:0)

一般我用

$output = trim(implode('-', array_map('ucfirst', explode('-', ucwords(strtolower(str_replace('_',' ',$input)))))));

如果您在数据库中存储_而不是空格,或者在网址中使用它们,那么也很方便地处理带连字符的名称。

在大多数情况下也看到这个似乎做得很好的地方

   /**
     * @param $string
     * @return string
     */
    public function titleCase($string)
    {

        $word_splitters = array(' ', '-', "O'", "L'", "D'", 'St.', 'Mc', 'Mac');
        $lowercase_exceptions = array('the', 'van', 'den', 'von', 'und', 'der', 'de', 'di', '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;
    }
像Jurgen Macho(一名足球运动员)这样的名字被归还为Jurgen MacHo,正如其他答案和评论所指出的那样,名字很难。