我有大量的字符串要在php中处理。我想“修复”它们作为标题大小写(使用ucwords(strtolower($str))
),但前提是它们都是大写或全部小写。如果它们已经是混合的情况,我只是将它们保留原样。
检查此问题的最快方法是什么?似乎for
通过字符串将是一种相当缓慢的方式。
这就是我所拥有的,我认为这会太慢了:
function fixCase($str)
{
$uc = 0;
$lc = 0;
for($i=0;$i<strlen($str);$i++)
{
if ($str[$i] >= 'a' && $str[$i] <= 'z')
$lc++;
else if ($str[$i] >= 'A' && $str[$i] <= 'Z')
$uc++;
}
if ($uc == 0 || $lc == 0)
{
return ucwords(strtolower($str));
}
}
答案 0 :(得分:6)
只使用字符串比较(区分大小写)
function fixCase($str)
{
if (
(strcmp($str, strtolower($str)) === 0) ||
(strcmp($str, strtoupper($str)) === 0) )
{
$str = ucwords(strtolower($str));
}
return $str;
}
答案 1 :(得分:1)
不会有任何惊人的优化,因为根据问题的本质,你需要看每个角色。
就个人而言,我会用这种算法循环遍历字符串的字符:
编辑:实际代码,我认为这与您将获得的一样好。
// returns 0 if non-alphabetic char, 1 if uppercase, 2 if lowercase
function getCharType($char)
{
if ($char >= 'A' && $char <= 'Z')
{
return 1;
}
else if ($char >= 'a' && $char <= 'z')
{
return 2;
}
else
{
return 0;
}
}
function fixCase($str)
{
for ($i = 0; $i < strlen($str); $i++)
{
$charType = getCharType($str[$i]);
if ($charType != 0)
{
$firstCharType = $charType;
break;
}
}
for ($i = $i + 1; $i < strlen($str); $i++)
{
$charType = getCharType($str[$i]);
if ($charType != $firstCharType && $charType != 0)
{
return $str;
}
}
if ($firstCharType == 1) // uppercase, need to convert to lower first
{
return ucwords(strtolower($str));
}
else if ($firstCharType == 2) // lowercase, can just ucwords() it
{
return ucwords($str);
}
else // there were no letters at all in the string, just return it
{
return $str;
}
}
答案 2 :(得分:1)
您可以尝试我发布here
的字符串案例测试功能function getStringCase($subject)
{
if (!empty($subject))
{
if (preg_match('/^[^A-Za-z]+$/', $subject))
return 0; // no alphabetic characters
else if (preg_match('/^[^A-Z]+$/', $subject))
return 1; // lowercase
else if (preg_match('/^[^a-z]+$/', $subject))
return 2; // uppercase
else
return 3; // mixed-case
}
else
{
return 0; // empty
}
}
答案 3 :(得分:1)
如果您想避免修复已经混合大小写的字符串的原因是为了提高效率,那么您可能会浪费时间,无论当前条件如何都要转换每个字符串:
function fixCase($str)
{
return ucwords(strtolower($str));
}
如果它比字符串的接受答案慢得多,那么我会非常惊讶你通常想要标题的长度,这是你需要担心的一个条件。
但是,如果有充分的理由避免转换已经混合的字符串,例如你想在套管中保留一些预期的含义,那么是的,jcinacio的答案当然是最简单和最有效的。
答案 4 :(得分:0)
检查string = lowercase(string)或string = uppercase(string)是否更容易,如果是,则保留它。否则执行您的操作。
答案 5 :(得分:0)
我决定对迄今为止提出的2个答案和我原来的解决方案进行测试。我不会想到结果会以这种方式结果,但我想原生方法比所有人都要快得多。
代码:
function method1($str)
{
if (strcmp($str, strtolower($str)) == 0)
{
return ucwords($str);
}
else if (strcmp($str, strtoupper($str)) == 0)
{
return ucwords(strtolower($str));
}
else
{
return $str;
}
}
// returns 0 if non-alphabetic char, 1 if uppercase, 2 if lowercase
function getCharType($char)
{
if ($char >= 'A' && $char <= 'Z')
{
return 1;
}
else if ($char >= 'a' && $char <= 'z')
{
return 2;
}
else
{
return 0;
}
}
function method2($str)
{
for ($i = 0; $i < strlen($str); $i++)
{
$charType = getCharType($str[$i]);
if ($charType != 0)
{
$firstCharType = $charType;
break;
}
}
for ($i = $i + 1; $i < strlen($str); $i++)
{
$charType = getCharType($str[$i]);
if ($charType != $firstCharType && $charType != 0)
{
return $str;
}
}
if ($firstCharType == 1) // uppercase, need to convert to lower first
{
return ucwords(strtolower($str));
}
else if ($firstCharType == 2) // lowercase, can just ucwords() it
{
return ucwords($str);
}
else // there were no letters at all in the string, just return it
{
return $str;
}
}
function method0($str)
{
$uc = 0;
$lc = 0;
for($i=0;$i<strlen($str);$i++)
{
if ($str[$i] >= 'a' && $str[$i] <= 'z')
$lc++;
else if ($str[$i] >= 'A' && $str[$i] <= 'Z')
$uc++;
}
if ($uc == 0 || $lc == 0)
{
return ucwords(strtolower($str));
}
}
function test($func,$s)
{
$start = gettimeofday(true);
for($i = 0; $i < 1000000; $i++)
{
$s4 = $func($s);
}
$end = gettimeofday(true);
echo "$func Time: " . ($end-$start) . " - Avg: ".sprintf("%.09f",(($end-$start)/1000000))."\n";
}
$s1 = "first String";
$s2 = "second string";
$s3 = "THIRD STRING";
test("method0",$s1);
test("method0",$s2);
test("method0",$s3);
test("method1",$s1);
test("method1",$s2);
test("method1",$s3);
test("method2",$s1);
test("method2",$s2);
test("method2",$s3);
结果:
method0 Time: 19.2899270058 - Avg: 0.000019290
method0 Time: 20.8679389954 - Avg: 0.000020868
method0 Time: 24.8917310238 - Avg: 0.00002489
method1 Time: 3.07466816902 - Avg: 0.000003075
method1 Time: 2.52559089661 - Avg: 0.000002526
method1 Time: 4.06261897087 - Avg: 0.000004063
method2 Time: 19.2718701363 - Avg: 0.000019272
method2 Time: 35.2485661507 - Avg: 0.000035249
method2 Time: 29.3357679844 - Avg: 0.000029336
答案 6 :(得分:0)
请注意,只要有重音符号或变音符号,任何只看[A-Z]的内容都会出错。如果结果不正确,优化速度是没有意义的(嘿,如果结果不一定正确,它可以为你写一个非常快速的实现...)