用于匹配的preg_match()vs strpos()?

jol*_*olt 31 php

对于单值检查,哪两个都是首选,为什么?

$string == 'The quick brown fox jumps over the lazy dog';

if(strpos($string, 'fox') !== false){
    // do the routine
}

# versus

if(preg_match('/fox/i', $string)){
    // do the routine
}
Run Code Online (Sandbox Code Playgroud)

小智 62

我更喜欢strpos结束preg_match,因为正则表达式通常更昂贵.

根据官方php文档preg_match:

preg_match()如果您只想检查另一个字符串中是否包含一个字符串,请不要使用.使用 strpos()strstr()替代,因为它们会更快.

  • 哇,在'preg_match();`文档中有一个巨大的提示,但像往常一样,我没有注意到它.好吧,谢谢你在这里复制粘贴.我猜这是我的问题由PHP工作人员自己解决. (4认同)

Mic*_*ski 13

如有疑问,请立即预测!

显然,我们可以提出一个比这更好的基准,但只是为了证明当它开始向上扩展时,strpos()将会更加快速.(差不多快2倍)

编辑我后来注意到正则表达式不区分大小写.当再次运行时使用stripos()更公平的比较,结果是11到15,因此差距变窄但preg_match()仍然慢得多.

$str = "the quick brown fox";
$start1 = time();
for ($i = 0; $i<10000000; $i++)
{
    if (strpos($str, 'fox') !== false)
    {
        //
    }
}
$end1 = time();
echo $end1 - $start1 . "\n";

$start2 = time();
for ($i = 0; $i<10000000; $i++)
{
    if (preg_match('/fox/i', $str))
    {
        //
    }
}
$end2 = time();
echo $end2 - $start2;

// Results:
strpos() = 8sec
preg_match() = 15sec

// Results both case-insensitive (stripos()):
stripos() = 11sec
preg_match() = 15sec
Run Code Online (Sandbox Code Playgroud)

  • 像这样的基准测试通常是没有意义的,因为你永远不会运行那个函数`10000000`次,甚至不是'100次'.有时`函数a`比`函数b`快,调用次数少,反之亦然.更不用说依赖于'time`或`microtime`是不好的,它使用的内部时钟可能是变量.相反,我会使用[xdebug](http://xdebug.org/). (3认同)

glo*_*tho 7

除非绝对必要,否则不要使用正则表 在像这样的字符串上启动和部署正则表达式引擎所涉及的开销类似于使用手提钻而不是普通锤,钻头而不是螺丝刀.

你还有一个更大的错误边缘与正则表达式 - 不匹配的字符串,意外的结果等.坚持strpos除非strpos不够灵活.

  • 自从我发布这个答案以来,我就没有使用过 PHP,但当时我非常喜欢性能调整,并从 Xdebug 配置文件和观察到许多写得不好的不必要密集的表达式得出这个结论。但是,如果我现在重写这个答案,我就不会这么极端了。我认为,纸杯蛋糕对 PHP 文档的回答和引用是一种更合适的语气。 (2认同)

ZJR*_*ZJR 5

如果您已经使用preg_matchpreg_replace在所有在你的代码的地方,然后再上,并再次使用它。为什么?

  1. 表现。这些函数添加的大部分开销都在引擎的初始加载时间,如果您已经付出了这个代价,那就值得了。

  2. 可读性。 strpos(...)!==false虽然速度更快,但令人难以置信

    它是最丑陋的php 结构之一。
    其中==和 的用法false非常笨拙,看起来难以解析且难以编辑。

strcontains()多年前,核心团队没有为它定义一个别名,这让他们感到羞耻。
现在这样做已经太晚了,但在那时会很好。

  • 实际上,当您熟悉 PHP 内部的类型处理时,使用 `!== false` 是非常有意义的。 (4认同)