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

时间:2011-06-22 00:17:43

标签: 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
}

6 个答案:

答案 0 :(得分:62)

我希望strpos超过preg_match,因为正则表达式的执行成本通常更高。

根据preg_match的官方php文档:

  

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

答案 1 :(得分: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

答案 2 :(得分:7)

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

你也有更大的误差,正则表达式 - 不匹配的字符串,意外的结果等。坚持使用strpos,除非strpos不够灵活。

答案 3 :(得分:4)

如果您已在代码中的所有位置使用preg_matchpreg_replace,请继续再次使用它。为什么呢?

  1. 性能。这些功能添加的大部分开销都是在引擎的初始加载时间内,如果您已经支付了这个价格,那就值得了。

  2. 可读性。 strpos(...)!==false虽然速度更快,却是不可思议的眼睛

    它是 ugliest php构造之一 使用==和。{ false里面的strcontains()真的很笨拙,很难解析和虚弱 编辑。

  3. 几年前,核心团队没有为它定义像{{1}}这样的别名 现在它已经太晚了这样做,但那时它会很好。

答案 4 :(得分:1)

因此,如果有人认为这种类型的东西具有任何重要性,请注意它在Big O中是常量。换句话说,数据库调用,On ^ 2或更糟糕的活动都是重要的。在大多数情况下,花时间去担心这些低级命令是没有意义的。并不是说应该忽略常量,例如,我重构了抓取图像的代码,因为它每次执行一次,每次花费1秒,然后将其从12秒减少到1秒(使用多卷曲请求)。关键是内置命令较低,代码结构更重要。

下面的代码是10万个电话,以及&#34;节省&#34;几乎没有。

function prof_flag($str)
{
    global $prof_timing, $prof_names;
    $prof_timing[] = microtime(true);
    $prof_names[] = $str;
}

function prof_print()
{
    global $prof_timing, $prof_names;
    $size = count($prof_timing);
    for($i=0;$i<$size - 1; $i++)
{
    echo "<b>{$prof_names[$i]}</b><br>";
        echo sprintf("&nbsp;&nbsp;&nbsp;%f<br>",     $prof_timing[$i+1]-$prof_timing[$i]);
    }
    echo "<b>{$prof_names[$size-1]}</b><br>";
}


$l = 10000000;
$str = "the quick brown fox";
echo "<h3>Ran " .number_format($l,2) ." calls per command </h3>";

prof_flag("Start: stripos");

for ($i = 0; $i<$l; $i++)
    if (stripos($str, 'fox') !== false) {}


prof_flag("Start: preg_match");

for ($i = 0; $i<$l; $i++)
    if (preg_match('#fox#i', $str) === 1) {}

prof_flag("Finished");
prof_print();

只有这段代码的价值在于它显示了一种很酷的方式来记录运行lol的时间

Ran 10,000,000.00 calls per command

Start: stripos
   2.217225
Start: preg_match
   3.788667
Start: ==
   0.511315
Start: ucwords lol
   2.112984
Finished

答案 5 :(得分:0)

您可以通过以下方式优化上述preg_match

preg_match('/(?>fox)/', $str)

这应该更快。