我有大量实时传入的短语需要通过单词和分割点转换为alpha only - CamelCase
。
这就是我到目前为止所提出的,但有没有更便宜,更快捷的方式来完成这项任务?
function FoxJourneyLikeACamelsHump(string $string): string {
$string = preg_replace("/[^[:alpha:][:space:]]/u", ' ', $string);
$string = ucwords($string);
$camelCase = preg_replace('/\s+/', '', $string);
return $camelCase;
}
// $expected = "ThQuCkBrWnFXJumpsVRThLZyDG";
$string = " Th3 qu!ck br0wn f0x jumps 0v3r th3 l@zy d0g. ";
$is = FoxJourneyLikeACamelsHump($string);
句子: 100000000
总时间: 40.844197034836 seconds
平均值 0.000000408
答案 0 :(得分:3)
您的代码效率很高。您仍然可以通过一些调整来改进:
ucwords
提供分隔符,这样就不必查找\t
,\n
等,这些内容在第一步之后就不会出现在字符串中。平均而言,这提高了1%; 代码:
function FoxJourneyLikeACamelsHump(string $string): string {
$string = preg_replace("/[^[:alpha:][:space:]]/u", ' ', $string);
$string = ucwords($string, ' ');
$camelCase = str_replace(' ', '', $string);
return $camelCase;
}
查看rextester.com上原始版和改进版的时间安排。
注意:正如您使用ucwords
一样,您的代码通常无法可靠地用于unicode字符串。为了弥补这一点,您需要使用mb_convert_case
之类的函数:
$string = mb_convert_case($string, MB_CASE_TITLE);
......但这会对性能产生影响。
答案 1 :(得分:1)
你可以试试这个正则表达式:
(?:\b|\d+)([a-z])|[\d+ +!.@]
UPDTAE(Run it here)
上面的想法是向你展示在正则表达式中应该如何工作:
以下是上述正则表达式的php实现。您可以将它与您的进行比较,因为这样可以通过单次替换操作完成操作:
<?php
$re = '/(?:\b|\d+)([a-z])|[\d+ +!.@]/';
$str = 'Th3 qu!ck br0wn f0x jumps 0v3r th3 l@zy d0g. ';
$subst=strtoupper('\\1');
$result = preg_replace_callback($re,function ($matches) {
return (isset($matches[1]) ? strtoupper($matches[1]) : '');
},$str);
echo $result;
?>
答案 2 :(得分:1)
对3种替代方案进行基准测试,我相信你的方法是最快的。以下是100,000次迭代的结果:
ID
array(4) {
["Test1"]=>
float(0.23144102096558)
["Test2"]=>
float(0.41140103340149)
["Test3"]=>
float(0.31215810775757)
["Test4"]=>
float(0.98423790931702)
}
是你的Test1
和Test2
是我的,而Test3
来自@ RizwanMTuman的答案(有修复)。
我认为使用Test4
可能会为您提供优化机会。在此函数中,仅使用1个正则表达式,并返回仅将您应用于preg_split
的alpha项目的数组:
ucfirst
使用function FoxJourneyLikeACamelsHump_2(string $string): string {
return implode('', array_map(function($word) {
return ucfirst($word);
}, preg_split("/[^[:alpha:]]/", $string, null, PREG_SPLIT_NO_EMPTY)));
}
代替foreach
(参见http://en.cppreference.com/w/cpp/language/template_specialization)可以进一步优化这一点:
array_map
这使我推测2个正则表达式和1个function FoxJourneyLikeACamelsHump_3(string $string): string {
$validItems = preg_split("/[^[:alpha:]]/u", $string, null, PREG_SPLIT_NO_EMPTY);
$result = '';
foreach($validItems as $item) {
$result .= ucfirst($item);
}
return $result;
}
比1个正则表达式和多个ucwords
更快。
完整的测试脚本:
ucfirst
答案 3 :(得分:0)
在考虑提高代码性能之前,首先需要构建一个有效的代码。实际上你正在尝试构建一个处理utf8编码字符串的代码(因为你在你的模式中添加了u修饰符);但是使用字符串liberté égalité fraternité
,您的代码会返回Liberté égalité Fraternité
而不是Liberté Égalité Fraternité
,因为ucwords
(或ucfirst
)无法处理multibyte characters
尝试了不同的方法(使用preg_split
和preg_replace_callback
)后,似乎这个preg_match_all
版本最快:
function FoxJourneyLikeACamelsHumpUPMA(string $string): string {
preg_match_all('~\pL+~u', $string, $m);
foreach ($m[0] as &$v) {
$v = mb_strtoupper(mb_substr($v, 0, 1)) . mb_strtolower(mb_substr($v, 1));
}
return implode('', $m[0]);
}
显然,它比你的初始代码慢,但我们无法真正比较这些不同的代码,因为你的代码不起作用。