优化ucallwords功能

时间:2014-12-08 15:21:11

标签: php

PHP中的ucwords函数并不认为非空白是字边界。所以,如果我说这个 - 那,我得到了这个 - 那个。我想要的是所有单词大写,例如This-That。

这是一个简单的功能。有人建议改善运行时间吗?

function ucallwords($s)
{
    $s = strtolower($s); // Just in case it isn't lowercased yet.
    $t = '';
    // Set t = only letters in s (spaces for all other characters)
    for($i=0; $i<strlen($s); $i++)
        if($s{$i}<'a' || $s{$i}>'z') $t.= ' ';
        else $t.= $s{$i};
    $t = ucwords($t);
    // Put the non-letter characters back in t
    for($i=0; $i<strlen($s); $i++)
        if($s{$i}<'a' || $s{$i}>'z') $t{$i} = $s{$i};
    return $t;
}

我的直觉是,这可以用正则表达式完成,但每次我开始处理它时,它变得复杂,我最终不得不处理其他事情。我忘记了我在做什么,我必须重新开始。我真正想听到的是PHP已经有一个很好的ucallwords功能,我可以使用它。

2 个答案:

答案 0 :(得分:0)

直接来自ucwords manual

  

jmarois at ca dot ibm dot com

<?php
//FUNCTION

function ucname($string) {
    $string =ucwords(strtolower($string));

    foreach (array('-', '\'') as $delimiter) {
      if (strpos($string, $delimiter)!==false) {
        $string =implode($delimiter, array_map('ucfirst', explode($delimiter, $string)));
      }
    }
    return $string;
}
?>
<?php
//TEST

$names =array(
  'JEAN-LUC PICARD',
  'MILES O\'BRIEN',
  'WILLIAM RIKER',
  'geordi la forge',
  'bEvErly CRuSHeR'
);
foreach ($names as $name) { print ucname("{$name}\n"); }

//PRINTS:
/*
Jean-Luc Picard
Miles O'Brien
William Riker
Geordi La Forge
Beverly Crusher
*/
?>
  

如果要处理更多字符,可以在for-each循环数组中添加更多分隔符。

答案 1 :(得分:0)

正则表达式很容易:

$s = 'this-that'; //Original string to uppercase.
$r = preg_replace('/(^|[^a-z])[a-z]/e', 'strtoupper("$0")', $s);

这假设$ s是小写的。您可以在第二行使用a-zA-Z来匹配大写和小写字母。或者,您可以使用strtolower($ s)将$ s包装在第二行。