0

PREG_PATTERN_ORDER文字列で見つかった値の位置を返すためにpreg_match_all を使用しました。次にsubstr、それらを参照しようとすると、それらは整列しません。オフセットを期待していましたが、ケースごとに未確定のずれがあるようです。

これは preg_match_all が文字ではなくバイトを返すためですか? もしそうなら、バイトを文字に変換する方法はありますか? 私が完全に的を外している場合は、いくつかのコードを投稿できます...

さて、適用可能なコードは次のとおりです。

// RETURN POSITION OF START AND END TAGS TO ARRAY
function getTagPositions($strBody, $start, $end)
{
    preg_match_all('/' . preg_quote($start, '/') . '([\w\s.]*?)'. preg_quote($end, '/').'/im', $strBody, $strTag, PREG_PATTERN_ORDER);
    $intOffset = 0;
    $intIndex = 0;
    $intTagPositions = array();

    foreach($strTag[0] as $strFullTag) {
        $intTagPositions[$intIndex] = array('start' => (strpos($strBody, $strFullTag, $intOffset)), 'end' => (strpos($strBody, $strFullTag, $intOffset) + strlen($strFullTag)));
        $intOffset += strlen($strFullTag);
        $intIndex++;
    }
    return $intTagPositions;
}

function arrayValRecursive($key, array $arr){
    $val = array();
    array_walk_recursive($arr, function($v, $k) use($key, &$val){
        if($k == $key) array_push($val, $v);
    });
    return count($val) > 1 ? $val : array_pop($val);
}

$arrayOfPositions = getTagPositions($html,$go,$stop);
$arrayOfStart = arrayValRecursive('start', $arrayOfPositions);   //print_r($arrayOfStart);
$arrayOfEnd = arrayValRecursive('end', $arrayOfPositions);   //print_r($arrayOfEnd);

  $offset = 0;
  $range = $arrayOfStart[$i] + $offset;
  $rangeEnd = $arrayOfEnd[$i];    
  echo '<br>'.$range.' to '.$rangeEnd.' is: <br>'; 
  echo substr($html, $range, $rangeEnd); 
4

1 に答える 1

1

preg_match_allによると

戻り値
完全なパターン一致の数 (ゼロの場合もあります) を返します。エラーが発生した場合は FALSE を返します。

文字列にオフセットを取得する場合は、使用しますPREG_OFFSET_CAPTURE

PREG_OFFSET_CAPTURE
このフラグが渡された場合、一致が発生するたびに、付属の文字列オフセットも返されます。これにより、matches の値が配列に変更されることに注意してください。ここで、すべての要素は、オフセット 0 の一致した文字列と、オフセット 1 の対象への文字列オフセットで構成される配列です。

次に例を示します。

$count = preg_match_all('/\S+/', 'Hello, world!', $matches, PREG_OFFSET_CAPTURE);
echo "count=$count\n";
var_dump($matches);

これは出力として与えます

count=2
array(1) {
  [0]=>
  array(2) {
    [0]=>
    array(2) {
      [0]=>
      string(6) "Hello,"
      [1]=>
      int(0)
    }
    [1]=>
    array(2) {
      [0]=>
      string(6) "world!"
      [1]=>
      int(7)
    }
  }
}

パターンが一致する$count=2回数を確認できます。位置で「Hello,」$matches[0][0][1]=0と一致し、「world!」と一致します。位置で$matches[0][1][1]=7

そして、これがすべての一致をループする方法です

$start = array();
$end = array();
foreach($matches[0] as $match) {
    $start[] = $match[1];
    $end[] = $match[1] + strlen($match[0]);
}
于 2012-12-12T21:30:29.963 に答える