private static function find($selector, $html, $start_from = 0)
{
$html = substr($html, $start_from);
$inner_start = 0;
$inner_end = 0;
$pattern = '//';
if (substr($selector, 0, 1) == '#') {
$pattern = '/<(\\w+)[^>]+id="' . substr($selector, 1) . '"[^>]*>/is';
} else {
if (substr($selector, 0, 1) == '.') {
$pattern = '/<(\\w+)[^>]+class="' . substr($selector, 1) . '"[^>]*>/is';
} else {
return false;
}
}
if (preg_match($pattern, $html, $matches, PREG_OFFSET_CAPTURE)) {
$outer_start = $matches[0][1];
$inner_start = $matches[0][1] + strlen($matches[0][0]);
// tag stuff
$tag_name = $matches[1][0];
$tag_len = strlen($tag_name);
$run_count = 300;
// "open" <tag elements we found so far
$open_count = 1;
$start = $inner_start;
while ($open_count != 0 && $run_count-- > 0) {
$open_tag = strpos($html, "<{$tag_name}", $start);
$close_tag = strpos($html, "</{$tag_name}", $start);
// nothing was found?
if ($open_tag === false && $close_tag === false) {
break;
}
//echo "open_tag: {$open_tag}, close_tag {$close_tag}\r\n";
// found OPEN tag
if ($close_tag === false || $open_tag !== false && $open_tag < $close_tag) {
$open_count++;
$start = $open_tag + $tag_len + 1;
//echo "found open tag: ".substr($html, $open_tag, 20)." at {$open_tag} \r\n";
// found CLOSE tag
} else {
if ($open_tag === false || $close_tag !== false && $close_tag < $open_tag) {
$open_count--;
$start = $close_tag + $tag_len + 2;
//echo "found close tag: ".substr($html, $close_tag, 20)." at {$close_tag} \r\n";
}
}
}
// something went wrong... don't bother returning anything
if ($open_count != 0) {
return false;
}
$outer_end = $close_tag + $tag_len + 3;
$inner_end = $close_tag;
return array('outer_start' => $outer_start + $start_from, 'inner_start' => $inner_start + $start_from, 'inner_end' => $inner_end + $start_from, 'outer_end' => $outer_end + $start_from);
}
return false;
}