Подсчет начальных и конечных HTML-тегов - PullRequest
1 голос
/ 25 августа 2011

Я ищу способ подсчета тегов html в куске html, используя php.Это может быть не полная веб-страница с тегами тела документа и т. Д.

Например:

Если бы у меня было что-то подобное

$string = "
<div></div>
<div style='blah'></div>
<p>hello</p>
<p>its debbie mcgee
<p class='pants'>missing p above</p>
<div></div>";

Я хочу пропуститьдля функции с именем тега, например

CheckHtml ($ string, 'p');

, и я хотел бы сообщить мне количество открытых тегов <p> и числоиз близких р тегов </p>.Я не хочу, чтобы это делало что-то необычное, кроме этого (никаких хитрых попыток исправить это).

Я пробовал с количеством строк с начальными тегами, такими как <p, но он слишком легко может найти такие вещи, как ивозвращать неверные результаты.

Я выглядел как DOMDocument, но он, кажется, не учитывает закрывающие теги и всегда ожидает <html> тегов (хотя я мог бы обойти это).

Любые предложенияна что использовать.

Ответы [ 4 ]

1 голос
/ 25 августа 2011

Чтобы получить точное количество, вы не можете использовать сопоставление строк или регулярное выражение из-за известных проблем синтаксического анализа HTML с регулярным выражением

Также вы не можете использовать выходные данные стандартного парсера, потому что это DOM, состоящий из элементов, и вся информация о тегах, которые были в HTML, была отброшена. Конечные теги будут выведены даже для действительного HTML, и даже некоторые начальные теги (например, html, head, body, tbody) могут быть выведены. Более того, такие вещи, как алгоритм агентства по усыновлению , могут привести к тому, что в разметке HTML будет больше элементов, чем было тегов. Например, <b><i></b>x</i> приведет к тому, что в DOM будет два i элемента. В то же время конечные теги, которые не могут быть сопоставлены с начальными тегами, просто отбрасываются, поскольку действительно могут начинать и заканчивать теги, которые появляются в неправильном месте. (например, <caption> не в <table> или <legend> не в <fieldset>)

Единственный способ, которым я могу думать, что вы можете сделать это надежным способом, это:

Есть PHP-библиотека с открытым исходным кодом для анализа HTML, которая называется html5lib .

Там есть файл с именем Tokenizer.php и в конце этого файла есть функция с именем emitToken. На этом этапе парсер выполнил всю работу по выяснению всех странностей HTML HTML, а параметр $token содержит всю информацию о том, какой тип токена был распознан, включая начальный и конечный теги.

Вы можете взять библиотеку и изменить ее так, чтобы она подсчитывала начальные и конечные маркеры тегов в этой точке, а затем выставляла эти итоги вашему коду приложения в конце процесса анализа.


¹: То есть он выяснил странности, связанные с вашей проблемой подсчета. не началось , чтобы выяснить странности конструкции дерева.

0 голосов
/ 25 августа 2011

substr_count кажется хорошей ставкой.

РЕДАКТИРОВАТЬ: Вам придется использовать preg_match тогда

Я не проверял, это, но, для идеи ..

function checkHTML($string,$htmlTag){
  $openTags = preg_match('/<'.$htmlTag.'\b[^>]*>',$string);
  $closeTags = preg_match('/<\/'.$htmlTag.'>/',$string);
  return array($openTags, $closeTags);
}

$numberOfParagraphTags = checkHTML($string,'p');

echo('Open Tags:'.$numberOfParagraphTags[0].' Close Tags:'.$numberOfParagraphTags[1]);
0 голосов
/ 25 августа 2011

Для фрагмента HTML попробуйте использовать класс PHP * DomDocument вместо строки.Затем вы можете использовать такие методы, как getElementsByTagName();, которые позволят вам подсчитывать теги проще и точнее.Чтобы загрузить вашу строку в DomDocument, вы можете сделать что-то вроде этого:

$doc = new DOMDocument();
$doc->loadHTML($string);

Затем, чтобы посчитать ваши теги, сделайте следующее:

$tagList = $doc->getElementsByTagName($tag);
return $tagList.length;
0 голосов
/ 25 августа 2011

Вы можете использовать substr_count () , чтобы возвратить количество раз, когда подстрока иглы встречается в стоге сена $string.

$open_tag_count = substring_count( $string, '<p' );
$close_tag_count = substring_count( $string, '</p>' );

Имейте в виду, что '

<pre, поэтому вам может потребоваться изменить поиск для обработки двух разных конкретных случаев:
$open_tag_count_without_attributes = substring_count( $string, '<p>' );
$open_tag_count_with_attributes = substring_count( $string, '<p ' );

$open_tag_count = $open_tag_count_without_attributes + $open_tag_count_with_attributes;

Вы также можете рассмотреть возможность использования [preg_match()][1]. Использование регулярного выражения для разбора HTML сопровождается довольно существенным набором ловушек , поэтому используйте его с осторожностью.

...