2012-12-12 82 views
0

我已使用preg_match_all的PREG_PATTERN_ORDER返回字符串中找到的值中的位置。然后当试图substr,引用他们回来,他们不排队。我预计会有一个偏移量,但每个案例似乎存在未确定的偏差。substr值不匹配preg_match_all PREG_PATTERN_ORDER

这是因为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); 
+0

你能后的代码? – jcjr

+0

[preg_match_all](http://php.net/manual/en/function.preg-match-all.php)“返回完整模式匹配的数量(可能为零),如果发生错误,则返回FALSE。”看起来你错误地使用了这个功能。 –

回答

1

根据preg_match_all

返回值
返回全模式匹配的数量(可能为零),或者如果发生错误,则为FALSE。

如果你想获得的偏移到字符串,用PREG_OFFSET_CAPTURE

PREG_OFFSET_CAPTURE
如果该标志,对每个出现的匹配结果附属的字符串偏移也将被退回。注意这改变匹配的值到一个数组,每一个元素是一个数组由匹配字符串中的偏移量为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倍。它匹配$matches[0][0][1]=0处的“你好”,它匹配“世界!”在位置$matches[0][1][1]=7

这里是你如何遍历所有匹配

$start = array(); 
$end = array(); 
foreach($matches[0] as $match) { 
    $start[] = $match[1]; 
    $end[] = $match[1] + strlen($match[0]); 
} 
+0

在使用'PREG_OFFSET_CAPTURE'查找解决方案后,我在php.net上找到了getTagPositions函数。你能否演示如何在这个函数中使用'PREG_OFFSET_CAPTURE'?谢谢。 – John

+0

@John查看最新的答案。这应该让你知道'$ matches'是如何用'PREG_OFFSET_CAPTURE'结构化的。 –

+0

谢谢你。到目前为止,我有这样的:'function arrayPositions($ string,$ start,$ end){count = preg_match_all('/'。preg_quote($ start,'/')。'([\ w \ s。] * ')'。preg_quote($ end,'/')'/',$ string,$ matches,PREG_OFFSET_CAPTURE); // echo“count = $ count \ n”; // var_dump($ matches); }'我如何获得所有“开始”值和另一个“结束”值的数组。通过将您的示例合并到函数中,它会打破arrayValRecursive函数。 – John