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…)
- 最干净的代码(高效编码)
- 最短代码
=
和==
的区别。
接下来,您已经有了一个字符串,可以搜索多个特定于字符串的函数:$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
。这是一个小小的进步。盲目地写下这句话,高兴地合并/放弃。是的,我也把你的改进融入了我的答案中,并戳了戳他