在php中使用perl regex匹配html标记。
如果标记在开放标记中的某处包含“class = details”,则希望标记匹配。
希望匹配<table border="0" class="details">
而不是<table border="0">
写这个以匹配它:
'#<table(.+?)class="details"(.+?)>#is'
<table(.+?)
会产生一个问题,因为它匹配的第一个表标记只有在找到class="details"
时才会停止匹配,无论代码发生多远。
我认为这个逻辑可以解决我的问题:
“匹配<table
但仅在下一个class="details"
之前包含>
”
我怎么写这个?
答案 0 :(得分:3)
虽然正则表达式可以适用于各种各样的任务,但我发现解析HTML DOM时通常会遇到这种情况。 HTML的问题在于,文档的结构变化很大,难以准确(并且准确地说,我的意思是100%的成功率,没有误报)提取标签。
我建议您使用DOM解析器,例如phpQuery
,并将其用作以下内容:
function get_first_image($html){
$dom = phpQuery::newDocument($html);
$first_img = $dom->find('img:first');
if($first_img !== null) {
return $first_img->attr('src');
}
return null;
}
有些人可能认为这样做有点过分,但最终,维护起来会更容易,并且还可以提供更多的可扩展性。例如,使用DOM解析器,我也可以获得alt属性。
可以设计一个正则表达式来实现相同的目标但是会限制它会强制alt
属性位于src
之后或相反的目标,并克服此限制会增加正则表达式的复杂性。
另外,请考虑以下内容。要使用正则表达式正确匹配<img>
标记并仅获取src
属性(在第2组中捕获),您需要以下正则表达式:
<\s*?img\s+[^>]*?\s*src\s*=\s*(["'])((\\?+.)*?)\1[^>]*?>
然后,如果出现以上情况,则上述情况可能会失败:
i
修饰符。src
属性周围没有使用引号。src
的另一个属性在其值的某处使用>
字符。所以再一次,不要使用正则表达式来解析dom文档。
有关如何使用phpQuery
解决问题的简单示例:
$dom = phpQuery::newDocument($html);
$matching_tags = $dom->find('.details');
答案 1 :(得分:1)
你可能需要在某种形式上保持积极的态度,作为一种非常粗略的形式,显然有其局限性......
<table(?=[^>]*class="details")[^>]*>
答案 2 :(得分:1)
HTML使用正则表达式无法解析(可靠)。很少有简单的案例有解决方案,但它们是例外。我认为你的案例使用正则表达式无法解决,但我不确定
您应该使用XML工具和XPath等XML解析器来搜索和测试您的条件。编写与您的案例相匹配的表达式非常简单。我不知道如何在PHP中构建XML树并执行XPath查询,但XPath表达式是
//table[@class='details']
答案 3 :(得分:0)
您可以使用如下所示的正则表达式:
<\/?table[^>]*(class="details")*>
但上述用户说使用xml / html类型解析器找到你的项目要好得多。