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) 

したがって、2つの問題が発生します。

  • twooの発生としてマークされていますtwo
  • ループは明らかに2回目の発生と一致しません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

将来の発生を見つけるために、最後に見つかった位置のオフセットを追加する必要があります。

誰かがすでにドキュメントコメント http://www.php.net/manual/en/function.strpos.php#107678でそのような解決策を提供しています

于 2012-05-14T15:41:56.617 に答える
0

最初のポイント:stristrを使用すると、すべての部分文字列が解決策として受け入れられるため、正規表現を使用することをお勧めします(preg_match_allを参照)。

2番目のポイント:配列のすべての要素について、干し草の山の先頭から文字列が検索され、最初の一致のみが取得されます。繰り返しますが、preg_match_allを使用してください!

于 2012-05-14T15:45:11.780 に答える