2

我试图在大海捞针中找到所有针的位置:

$haystack = 'one twoo two one postpone twool';
$needles = array('one', 'two', 'three');
foreach ($needles as $needle) { 
  if (stristr($haystack, $needle)) { // list position of all needles
    $pos[strpos($haystack, $needle)] = $needle;
  }
}
print_r($pos);

的值在$pos这里:

Array ( [0] => one [4] => two ) 

然而,预期是:

Array ( [0] => one [9] => two [13] => one) 

所以有两件事出错了:

  • twoo被标记为发生two
  • 循环显然与第二次出现不匹配one

我究竟做错了什么?

4

5 回答 5

2

如果你想要一个简单的方法,你可以使用preg_match

foreach ($needles as $needle) {
    if( preg_match_all( '/\b' . $needle . '\b/', $haystack, $matches, PREG_OFFSET_CAPTURE ) ) {
        foreach( $matches[0] as $match )
            $pos[$match[1]] = $needle;
    }
}
于 2012-05-14T15:47:51.997 回答
1

根据 Rawkode 的建议:

function strpos_recursive($haystack, $needle, $offset = 0, &$results = array()) {                
    $offset = strpos($haystack, $needle, $offset);
    if($offset === false) {
        return $results;            
    } else {
        if(substr ($haystack, $offset + strlen ($needle), 1) == ' ' || ( $offset + strlen ($needle) ) == strlen ($haystack)) {  
            if(substr ($haystack, $offset - 1, 1) == ' ' || $offset == 0) {
                $results[$offset] = $needle;
            }
        }
        return strpos_recursive($haystack, $needle, ($offset + 1), $results);
    }
}

$haystack = 'one twoo two one postpone twool one three';
$needles = array('one', 'two', 'three');
$pos = array ();

foreach ($needles as $needle) { 
    if (stristr($haystack, $needle)) {
        $pos += strpos_recursive($haystack, $needle);
    }
}
ksort($pos);
print_r($pos);

我还添加了一个检查以确保下一个字符是空格或者它已经是大海捞针的尽头,所以它不会匹配twoo.

于 2012-05-14T15:44:19.790 回答
1

你应该使用正则表达式。尝试这个:

$haystack = 'one twoo two one postpone twool';
$needles = array('one', 'two', 'three');

foreach($needles as $needle) 
{
    $regex = "/\b$needle\b/";

    if (preg_match_all($regex, $haystack, $matches, PREG_OFFSET_CAPTURE))
    {
        if (is_array($matches[0]))
        {
            foreach($matches[0] as $match)
            {
                $pos[$match[1]] = $match[0];
            }
        }

    }
}

print_r($pos);

输出是:

Array
(
    [0] => one
    [13] => one
    [9] => two
)
于 2012-05-14T16:10:57.670 回答
0

第一点:使用 stristr 每个子字符串都被接受为解决方案,所以我建议使用正则表达式(参见 preg_match_all)。

第二点:对于数组的每个元素,从大海捞针的开头开始搜索字符串,并且只取第一个匹配项。再次使用 preg_match_all!

于 2012-05-14T15:45:11.780 回答
0

您需要添加最后找到的位置的偏移量才能找到未来的事件。

有人已经在文档评论 http://www.php.net/manual/en/function.strpos.php#107678上提供了这样的解决方案

于 2012-05-14T15:41:56.617 回答