计算开始和结束html标记

时间:2011-08-24 20:11:05

标签: php html tags count validation

我正在寻找一种方法来使用php计算一大块html中的html标签。这可能不是带有doctype body标签等的完整网页。

例如:

如果我有这样的事情

$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>的数量。我不希望它做任何花哨的事情(没有偷偷摸摸地试图解决它)。

我尝试使用<p这样的开始标记进行字符串计数,但它很容易找到类似的内容并返回错误的结果。

我看了一下DOMDocument,但似乎没有计算关闭标签,总是需要<html>标签(虽然我可以解决这个问题)。

有关使用内容的任何建议。

4 个答案:

答案 0 :(得分:1)

要获得准确的计数,由于well-known problems of parsing HTML with regex

,您无法使用字符串匹配或正则表达式

您也不能使用标准解析器的输出,因为这是一个由元素组成的DOM,并且丢弃了HTML中标记的所有信息。即使对于有效的HTML,也会推断出结束标记,甚至可以推断出一些开始标记(例如html,head,body,tbody)。此外,the adoption agency algorithm之类的内容可能会导致HTML标记中的标记数量多于元素。例如,<b><i></b>x</i>将导致DOM中有两个i个元素。同时,简单地丢弃无法与开始标记匹配的结束标记,因为实际上可以开始和结束出现在错误位置的标记。 (例如<caption>不在<table><legend>不在<fieldset>

我认为你可以以任何方式可靠地做到这一点的唯一方法是:

有一个用于解析HTML的开源PHP库,名为html5lib

在那里,有一个名为Tokenizer.php的文件,在该文件的末尾有一个名为emitToken的函数。此时,解析器完成了查找所有HTML怪异¹的所有工作,$token参数包含有关已识别哪种令牌的所有信息,包括开始和结束标记。

您可以使用该库并对其进行修改,以便在此时计算开始和结束标记令牌,然后在解析过程结束时将这些总计公开给您的应用程序代码。


¹:也就是说,它找出了与你的计数问题有关的奇怪之处。它还没有开始来弄清楚树形结构的奇怪之处。

答案 1 :(得分:0)

您可以使用substr_count()返回大海捞针$string中针子串发生的次数。

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

请注意'&lt; param和<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时带有fairly substantial set of pitfalls,因此请谨慎使用。

答案 2 :(得分:0)

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]);

答案 3 :(得分:0)

对于HTML的大块,请尝试使用DomDocument PHP类而不是字符串。然后,您可以使用getElementsByTagName();等方法,以便更轻松,更准确地计算代码。要将字符串加载到DomDocument,您可以执行以下操作:

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

然后,要计算您的代码,请执行以下操作:

$tagList = $doc->getElementsByTagName($tag);
return $tagList.length;