Does anyone have a good Proper Case algorithm

前端 未结 13 1205
一生所求
一生所求 2020-12-15 04:03

Does anyone have a trusted Proper Case or PCase algorithm (similar to a UCase or Upper)? I\'m looking for something that takes a value such as \"GEORGE BURDELL\"

相关标签:
13条回答
  • 2020-12-15 05:09

    I wrote this today to implement in an app I'm working on. I think this code is pretty self explanatory with comments. It's not 100% accurate in all cases but it will handle most of your western names easily.

    Examples:

    mary-jane => Mary-Jane

    o'brien => O'Brien

    Joël VON WINTEREGG => Joël von Winteregg

    jose de la acosta => Jose de la Acosta

    The code is extensible in that you may add any string value to the arrays at the top to suit your needs. Please study it and add any special feature that may be required.

    function name_title_case($str)
    {
      // name parts that should be lowercase in most cases
      $ok_to_be_lower = array('av','af','da','dal','de','del','der','di','la','le','van','der','den','vel','von');
      // name parts that should be lower even if at the beginning of a name
      $always_lower   = array('van', 'der');
    
      // Create an array from the parts of the string passed in
      $parts = explode(" ", mb_strtolower($str));
    
      foreach ($parts as $part)
      {
        (in_array($part, $ok_to_be_lower)) ? $rules[$part] = 'nocaps' : $rules[$part] = 'caps';
      }
    
      // Determine the first part in the string
      reset($rules);
      $first_part = key($rules);
    
      // Loop through and cap-or-dont-cap
      foreach ($rules as $part => $rule)
      {
        if ($rule == 'caps')
        {
          // ucfirst() words and also takes into account apostrophes and hyphens like this:
          // O'brien -> O'Brien || mary-kaye -> Mary-Kaye
          $part = str_replace('- ','-',ucwords(str_replace('-','- ', $part)));
          $c13n[] = str_replace('\' ', '\'', ucwords(str_replace('\'', '\' ', $part)));
        }
        else if ($part == $first_part && !in_array($part, $always_lower))
        {
          // If the first part of the string is ok_to_be_lower, cap it anyway
          $c13n[] = ucfirst($part);
        }
        else
        {
          $c13n[] = $part;
        }
      }
    
      $titleized = implode(' ', $c13n);
    
      return trim($titleized);
    }
    
    0 讨论(0)
提交回复
热议问题