正则表达式按类名提取元素

时间:2009-07-30 14:08:36

标签: html regex parsing

问候!

我有一些HTML可能有效,也可能无效。如果HTML无效,则可以进行最佳尝试,并且出现的任何错误都是可接受的(即,由于某些标记未正确关闭,因此分组过多)。

在这个HTML中有各种各样的元素,其中一些可能有一个类(称之为“findme”)。这些元素的类型各不相同;一些 img ,一些对象,一些一个等。

我需要一个正则表达式来提取所有元素,以及它们包含内容时包含的内容。

例如:

<div>
<span><img class="findme" src="something" /></span>
<object class="findme" classid="clsid:F08DF954-8592-11D1-B16A-00C0F0283628" id="Slider1" width="100" height="50">
  <param name="BorderStyle" value="1" />
  <param name="MousePointer" value="0" />
  <param name="Enabled" value="1" />
  <param name="Min" value="0" />
  <param name="Max" value="10" />
</object>
</div>

在那块HTML上运行正则表达式应返回2个元素:

<img class="findme" src="something" />

<object class="findme" classid="clsid:F08DF954-8592-11D1-B16A-00C0F0283628" id="Slider1" width="100" height="50">
      <param name="BorderStyle" value="1" />
      <param name="MousePointer" value="0" />
      <param name="Enabled" value="1" />
      <param name="Min" value="0" />
      <param name="Max" value="10" />
    </object>

你们中的任何一个正则大师都对这个有一个想法吗?

编辑: 语言是c#。

5 个答案:

答案 0 :(得分:4)

虽然正则表达式可以适用于各种各样的任务,但我发现解析HTML DOM时通常会遇到这种情况。 HTML的问题在于,文档的结构变化很大,难以准确(并且准确地说,我的意思是100%的成功率,没有误报)提取标签。

我建议您使用DOM解析器,例如SimpleHTML,并将其用作以下内容:

require_once('SimpleHTML.class.php')

$html_dom = str_get_dom($html);
$tags = $html_dom->find('img.findme'); // Get all img elements of class findme

有些人可能认为这样做有点过分,但最终,维护起来会更容易,并且还可以提供更多的可扩展性。例如,使用DOM解析器,我也可以获得alt属性。

可以设计一个正则表达式来实现相同的目标但是会限制它会强制alt属性位于src之后或相反的​​目标,并克服此限制会增加正则表达式的复杂性。

另外,请考虑以下内容。要使用正则表达式正确匹配<img>标记并仅获取class属性(在第2组中捕获),您需要以下正则表达式:

<\s*img\s+[^>]*?\s*class\s*=\s*(["'])((\\?+.)*?)\1[^>]*?>

然后,如果出现以上情况,则上述情况可能会失败:

  • 属性或标记名称为大写,并且不使用 i 修饰符。
  • class属性周围没有使用引号。
  • 然后class的另一个属性在其值的某处使用>字符。
  • 我没有预料到的其他一些原因。

所以再一次,不要使用正则表达式来解析dom文档。

答案 1 :(得分:2)

正则表达式是这项工作极其糟糕的工具。使用解析器。在此之前,通过HTML Tidy运行它来修复无效的HTML。无论你使用什么语言(你没说),都会有一个或多个HTML解析器。

答案 2 :(得分:0)

而不是尝试使用原始regex操作直接解决此问题, 您应该考虑使用您熟悉的任何语言中的 HTML Parser模块 在这里列出一些引用,

答案 3 :(得分:0)

您没有提到您正在使用的语言,但您可能应该将其加载到XmlDocument中并正确搜索DOM。正则表达式将模式匹配,但你可能得到各种误报。

答案 4 :(得分:0)

试图用正则表达式解决这类问题是一个令人讨厌的方法。如果您正在使用服务器,请使用容错的html解析器解析代码段(例如,针对ruby的hpricot)并对dom进行验证。 使用el.innerHTML =“...”

可以在客户端上完成相同的操作