【问题标题】:CamelCase to LowerDashCase - Without RegexCamelCase 到 LowerDashCase - 没有正则表达式
【发布时间】:2014-08-02 23:44:55
【问题描述】:

我有以下功能:

function dashesToCamelCase($string)
{
    return str_replace(' ', '', ucwords(str_replace('-', ' ', $string)));
}

function camelCaseToDashes($string) {
    //This method should not have Regex
    $string = preg_replace('/\B([A-Z])/', '-$1', $string);
    return strtolower($string);
}

这是一个测试:

$testArray = ['UserProfile', 'UserSettings', 'Settings', 'SuperLongString'];

foreach ($testArray as $testData) {
    $dashed = camelCaseToDashes($testData);
    $orignal = dashesToCamelCase($dashed);
    echo '<pre>' . $dashed . ' | ' . $orignal . '</pre>';
}

这是预期的输出:

user-profile      | UserProfile
user-settings     | UserSettings
settings          | Settings
super-long-string | SuperLongString

现在我的问题:方法camelCaseToDashes 现在正在使用Regex。你能想象没有Regex 的更好(更快)实现吗?

【问题讨论】:

  • 这是一个过早的优化
  • Regex 实现已经使用可用的最佳内置函数进行了优化,甚至使用 C 代码编写为 PHP 模块的一些底层优化。你不需要重新发明轮子......
  • 感谢@HenriqueBarcelos,只是认为这不是“常规问题”,因为很多人说:避免使用正则表达式。但是这个例子(以及相应的基准答案)让我大开眼界。

标签: php regex review


【解决方案1】:

在优化错误的东西之前,您真的应该首先检查分析器图。

可视化您的preg_replace 的实际执行时间。

用各种 PHP 字符串函数变通方法替换正则表达式通常不是优化。

【讨论】:

  • 好吧,Regex 似乎是最快的解决方案。谢谢你的照片。请问你用的是什么工具?
  • 那只是kcachegrind
【解决方案2】:

试试这个:

$text = 'CamelCaseString';

$result = '';
for ($i = 0; $i < strlen($text); $i++) {
    $result .= $i > 0 && ord($text[$i]) >= 64 && ord($text[$i]) <= 90 ? '-'.$text[$i] : $text[$i];
}

var_dump(strtolower($result));

您可以创建一个基准来查看每个解决方案的性能。

实际上,根据我的基准,使用正则表达式的解决方案似乎快了大约 10 倍:

$ php test2.php regex: 0.41732287406921 without regex: 3.5226600170135

我想,那个正则表达式会更好,因为它是用 C 实现的。我的算法是用 PHP 实现的,它的性能要差得多。通过一些优化,我能够将算法的 100,000 次迭代的时间缩短到 2.5 秒(相比之下,正则表达式的 100,000 次迭代需要 0.4 秒)。

改进版:

$text = 'CamelCaseString';

$result = '';
$lenght = strlen($text);
for ($i = 0; $i < $lenght; $i++) {
    $ord = ($text[$i]);
    $result .= $i > 0 && $ord >= 64 && $ord <= 90 ? '-'.$text[$i] : $text[$i];
}

$ php test2.php regex: 0.40657687187195 without regex: 2.5361099243164

还有一件有趣的事:

正如您在函数配置文件中所见,函数 preg_replace 只占用总时间的 12%,strtolower 占用不到 1%。函数regex 中没有其他代码。但这可能是Xdebug 的开销。个人资料由qCacheGrind 可视化。

【讨论】:

  • 感谢您的回复。我插入了ltrim ($result,'-') 并对其进行了基准测试。您的方法需要两次,然后使用正则表达式。但是感谢您的解决方案。
  • 这是我的错,但我已经解决了这个问题,现在不需要ltrim。我认为您的正则表达式解决方案已经足够好了:)
  • 希望加倍支持,因为您为这个问题投入了很多时间,并且现在已经进行了 3 次编辑,每 1 次支持对我来说都值得 :) 你真的帮了我 :) 甚至学会了新事物,您可以将字符串作为 char 数组访问并获取 char 代码:)
  • 太棒了!听到我帮助某人真的很高兴,因此值得花时间去做这件事。而且我也可以学习一些新的东西。例如,正则表达式具有相当好的性能。此外,我真的建议您使用 Xdebug 进行(但不仅是)分析。您可以使用例如kCacheGrindqCacheGrindXCallGraph 来可视化生成的配置文件,以查看每个函数在脚本中占用的时间。
【解决方案3】:

如果你想获得可笑的收益,试试这个:

function dashesToCamelCase2($string) {
    return strtr(ucwords(strtr($string, '-', ' ')), ' ', '');
}

function camelCaseToDashes2($string) {
    return strtolower(preg_replace('/(?=[A-Z])\B/', '-', $string));
}

【讨论】:

    猜你喜欢
    • 2012-11-23
    • 1970-01-01
    • 2014-02-15
    • 2011-09-13
    • 2011-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多