PHP-这是进行这些更改的有效方法吗?

PHP-这是进行这些更改的有效方法吗?,php,Php,我非常关心资本化(可能太多了)。所以我写了一个函数,修复了我网站上所有地方的大写字母。我基本上想要“标题案例”,但除了一些例外。。。我不喜欢看到大写和首字母缩略词的单词 function my_capitals($string) { $uc = ucwords($string); $tokens = explode(' ',$uc); foreach ($tokens as $key=>$val) { if ($val == 'Ipa') $

我非常关心资本化(可能太多了)。所以我写了一个函数,修复了我网站上所有地方的大写字母。我基本上想要“标题案例”,但除了一些例外。。。我不喜欢看到大写和首字母缩略词的单词

function my_capitals($string)
{
    $uc = ucwords($string);
    $tokens = explode(' ',$uc);
    foreach ($tokens as $key=>$val)
    {
        if ($val == 'Ipa') $tokens[$key] = 'IPA';
        else if ($val == 'Ipas') $tokens[$key] = 'IPAs';
        else if ($val == 'Apa') $tokens[$key] = 'APA';
        else if ($val == 'Apas') $tokens[$key] = 'APAs';
        else if ($val == 'A') $tokens[$key] = 'a';
        else if ($val == 'And') $tokens[$key] = 'and';
        else if ($val == 'The') $tokens[$key] = 'the';
        else if ($val == 'In') $tokens[$key] = 'in';
        else if ($val == 'Or') $tokens[$key] = 'or';
        else if ($val == 'Of') $tokens[$key] = 'of';
        else if ($val == 'To') $tokens[$key] = 'to';
        else if ($val == 'On') $tokens[$key] = 'on';
        else if ($val == 'At') $tokens[$key] = 'at';
        else $tokens[$key] = $val;
    }
    $final = implode(' ',$tokens);
    return $final;
}
想象一下,可能还有10-15个选项,并且它可能在相对较短的字符串(单行描述和标题)上每页运行3-5次


我的问题是:这是完成此类翻译的有效方法吗?还是我应该想出一个更有效的方法来做?除了可能具有类似性能的开关之外,还有其他选择吗?

我会这样做:

   function my_capitals($string)
    {
        $uc = ucwords($string);
        $tokens = explode(' ',$uc);
        $excepsions = ['Ipa'=>'IPA','Ipas'=>'IPAs'];
        foreach ($tokens as $key=>$val)
        {
            if(isset($excepsions[$val])){
                $tokens[$key] = $excepsions[$val];
            }
        }
        $final = implode(' ',$tokens);
        return $final;
    }

首先,你必须考虑<强>有效< >强>对你意味着什么。你在找什么

  • 最短执行时间
  • 系统影响最小(CPU、RAM、I/O…)
  • 最干净的代码(高效编码)
  • 最短代码
第二,考虑到你的细节

  • 大约有30个搜索词
  • 弦很短
  • 代码最多被激发5次
  • 。。。除非您在脚本中使用烤面包机,否则执行时间和系统影响都不会让您头痛

    所以这实际上取决于一个干净的代码。因此,您应该了解
    =
    ==
    的区别。 接下来,您已经有了一个字符串,可以搜索多个特定于字符串的函数:
    $uc

    那怎么办?它接受数组作为输入

    function my_capitals($string)
    {
        $uc = " ".ucwords($string)." ";
        $search = [' Ipa ', ' Ipas ', ' A ', ' Bändy '];
        $replacements = [' IPA ', ' IPAs ', ' a ', ' Cändy '];
        return ucfirst(trim(str_replace($search, $replacements, $uc)));
    }
    
    您甚至可以将其缩短为一行:

    function my_capitals($string)
    {
        return ucfirst(trim(str_replace([' Ipa ', ' Ipas ', ' A ', ' Bändy '], [' IPA ', ' IPAs ', ' a ', ' Cändy '], " ".ucwords($string)." ")));
    }
    
    只需确保
    $search
    $replacements
    包含等量的元素,并且都有前导和尾随空格

    只分配一次阵列将提高连续呼叫的速度

    function my_capitals1a($string, $searcher, $replacement)
    {
        return ucfirst(trim(str_replace($searcher,$replacement, " ".ucwords($string)." ")));
    }
    
    演示和速度比较:

    编辑:word安全替换 编辑2:速度比较
    Edit3:通过@Pogrock的提示进行了改进,OP的代码略有变化。大写输入标题中的所有单词,然后将and之类的单词替换为and。最后初始化标题的开头

    您可以先将标题规范化,并将字符串改为小写,但这可能会破坏诸如O'Hagan之类的名称

    还有许多其他边缘案例未涵盖,您最好以速度换取功能齐全的库

    <?php
    $replacements = [
            'Ipas' => 'IPAs',
            'Apa'  => 'APA',
            'Apas' => 'APAs',
            'A'    => 'a',
            'And'  => 'and',
            'The'  => 'the',
            'In'   => 'in',
            'Or'   => 'or',
            'Of'   => 'of',
            'To'   => 'to',
            'On'   => 'on',
            'At'   => 'at',
    ];
    
    $test_titles = [
        'a tale of two cities'    => 'A Tale of Two Cities', 
        'the secret history'      => 'The Secret History',
        'lord of the flies'       => 'Lord of the Flies',
        'The woman in white'      => 'The Woman in White',
        'of mice and men'         => 'Of Mice and Men',
        'the andy warhol diaries' => 'The Andy Warhol Diaries'
    ];
    
    foreach($test_titles as $input => $title_cased) {
        $words = [];
        foreach(explode(' ', ucwords($input)) as $word) {
            $words[] = isset($replacements[$word]) ? $replacements[$word] : $word;
        }
        $transformed = ucfirst(implode(' ', $words));
        assert($transformed === $title_cased);
    }
    

    新行大写字母是否可能重复?你也想要那些小写字母吗?@Haroon,我不这么认为,因为我不是在问switch是否比if/else快,我是在问是否有更好的方法来实现这一点,可能包括switch以外的解决方案。看起来你正在尝试转换为“标题格”。你可能不想用“And”开头一句话,但很多都是以“The”开头的。标题框有很多不同的样式。也许可以选择一个适合您的现有库。相关报道:好吧,我现在同意了,我很抱歉我把它标记为重复。我开始用“重构”的方式来做这件事,但我不确定它是否会更有效。谢谢您的建议。您的
    isset
    clause@rndus2r谢谢不管怎样,我认为你的答案要好得多。你可能需要在上面留下空格。e、 “安迪”。谢谢你提供了一些思考问题的框架。我特别感兴趣的是最短的执行时间。我是唯一一个阅读代码的人,虽然我为自己未来的理智自由地发表评论,但干净/简短的代码并不是我最优先考虑的。我以前复习过==vs==。我第一次了解到区别在于类型,因为这些都是字符串,所以我认为我很擅长使用==。事实证明===更快,所以谢谢!!)。我将探索stru_替换效率。谢谢@Progrock谢谢你指出这一点,我已经更新了answer@rndus2r,当然,其他标点符号,如连字符和逗号,以及句子中的最后一个单词也可能会造成问题。请原谅:)只要您定义自定义搜索和替换,您就可以自由选择。我在答案中添加了一个速度比较,并对其进行了改进。在你的例子中,70万次循环,大约是140.000到233.333页的呼叫。与@Andriy Lozynskiy answer有什么区别?@rndus2r从哪里开始?他们的函数有一个语法错误,即使更正了也不起作用。它只是缺少了a)并且工作正常:@rndus2r,一旦修复并充实,类似的。但最后没有
    ucfirst
    。这是一个小小的进步。盲目地写下这句话,高兴地合并/放弃。是的,我也把你的改进融入了我的答案中,并戳了戳他