2012-12-12 121 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