while循环中的strpos()永远不会结束

时间:2013-02-18 06:56:07

标签: php while-loop strpos

有一个字符串,

  

$ string ='Foo,Bar,Test,';

我想做的就是计算字符串中逗号的数量。

但是一切都会导致无限循环。

所以,我试过#1:

$ count = 0;

while($pos = strpos($string, ',') !== FALSE){
    $count++;
    // Never ends
}

还有#2,

while(true){
  if ( strpos($string, ',') !== FALSE ){
     $count++;
  } else {
    break;
  }
}

他们都没有结束。问题出在哪里?

4 个答案:

答案 0 :(得分:4)

您可以使用substr_count()

substr_count($string, ',');

在您的代码中,strpos()需要第三个参数才能从特定偏移开始搜索,例如:

strpos($string, ',', 12); // start searching from index 12

它不像迭代器那样工作。像这样的东西会起作用:

$start = 0;
while (($pos = strpos($string, ',', $start)) !== FALSE) {
  $count++;
  $start = $pos + 1;
}

<强>更新

如果你想得到真正的幻想:

class IndexOfIterator implements Iterator
{
  private $haystack;
  private $needle;

  private $start;
  private $pos;
  private $len;
  private $key;

  public function __construct($haystack, $needle, $start = 0)
  {
    $this->haystack = $haystack;
    $this->needle = $needle;
    $this->start = $start;
  }

  public function rewind()
  {
    $this->search($this->start);
    $this->key = 0;
  }

  public function valid()
  {
    return $this->pos !== false;
  }

  public function next()
  {
    $this->search($this->pos + 1);
    ++$this->key;
  }

  public function current()
  {
    return $this->pos;
  }

  public function key()
  {
    return $this->key;
  }

  private function search($pos)
  {
    $this->pos = strpos($this->haystack, $this->needle, $pos);
  }
}

foreach (new IndexOfIterator($string, ',') as $match) {
  var_dump($match);
}

答案 1 :(得分:2)

试试这个:

$text = 'Foo, Bar, Test,';
echo substr_count($text, ',');

参考:http://php.net/manual/en/function.substr-count.php

答案 2 :(得分:2)

strpos()会返回$needle的第一个匹配项,因此除非您指定不同的$offset,否则您将始终获得相同的结果,因此无限循环。

如果您坚持使用strpos(),请尝试以下操作:

$pos=0;
while(($pos = strpos($string, ',',$pos)) !== FALSE){
    $count++;
    $pos++;
    // This ends
}

当然,您可以使用substr_count()来简化操作。

修改

Live demo

答案 3 :(得分:0)

如果substr_count不适合,请尝试此操作:

$pos = -1;
$count=0;
while( $pos = strpos($in, ',', $pos+1) !== FALSE){
     $count++;
     }

我没有测试你是否绝对需要!== FALSE。如果你使用mb_strpos,你就不会。