strpos of 0 打破 while 循环

strpos of 0 breaking while loop

所以我再次练习 PHP。具体来说 strpos() 在 while 循环中。

下面代码的问题在于 strpos() 在第一个循环中导致 0,这会在 while 条件下产生 false 结果,从而终止循环。

$string = 'orem ipsum dolor sit amet, consectetur adipisicing elit.';
$find = 'o';
$offset = 0;
$length  = strlen($find);

while ($string_pos = strpos($string, $find, $offset)) {
    echo 'String '.$find.' found at position '.$string_pos.'.<br>';
    $offset = $length + $string_pos;
}

我对这一切都很陌生,有人可以帮我解释一下并提供解决方案吗?我正在寻找它来循环所有事件。

如果你不想使用strpos():

<?php

$string = 'orem ipsum dolor sit amet, consectetur adipisicing elit.';
$find = 'o';

for($i = 0; $i <= strlen($string)-1; $i++){
    // we are checking with each index of the string here
    if($string[$i] == $find){
        echo 'String '.$find.' found at position '.$i.'.<br>';
    }
}

?>

我不太喜欢 Jigar 的 "iterate every character" 回答,因为当找不到更多的针时,它不会提供快速退出(无论如何它都会迭代整个字符串)——这可以在更长的字符串中变得更昂贵。假设您有一个 10,000 个字符的字符串,并且唯一出现的针出现在第一个字符上——这意味着要进行 9999 次以上的迭代检查以确保没有可用的输出。事实是我没有做任何基准测试,这可能根本不是什么大问题。

至于你的方法,你只需要对strpos()的结果进行严格比较,这样php就能正确区分false0 结果。为此,您只需将 strpos() 声明括在括号中并编写特定于类型的比较 (!==false).

这里有另外两种方式(非正则表达式和正则表达式):

代码:(Demo)

$string='orem ipsum dolor sit amet, consectetur adipisicing elit.';
$find='o';
$offset=0;
$length=strlen($find);

while(($string_pos=strpos($string,$find,$offset))!==false){  // just use a strict comparison
    echo "String $find found at position $string_pos\n";
    $offset=$length+$string_pos;
}

echo "\n";
var_export(preg_match_all('/o/',$string,$out,PREG_OFFSET_CAPTURE)?array_column($out[0],1):'no matches');

输出:

String o found at position 0
String o found at position 12
String o found at position 14
String o found at position 28

array (
  0 => 0,
  1 => 12,
  2 => 14,
  3 => 28,
)

对于您的情况,preg_match_all() 一切都太过分了。但是,如果您想计算多个不同的单词、整个单词或其他棘手的事情,它可能是正确的工具。

除此之外,根据搜索场景,str_word_count() 有一个设置,它可以 return 字符串中所有单词的偏移量——然后你可以调用过滤函数只保留你想要的词。只是想我会为未来的读者提出这个建议;它不适用于这个问题。