我有一个cURL函数可以抓取指定页面上的所有内容,但我只想要body标签之间的元素。我发现这个漂亮的正则表达式可以匹配<body>
和</body>
之间的所有内容。但后来我意识到我需要使用cURL的其中一个页面实际上有一个带有样式信息的body标签,所以我真正想要匹配的是 <body style=...>
之间的所有和</body>
。有谁知道正则表达式匹配那个?到目前为止,这是我的所有代码......
<?php
error_reporting(E_ALL);
ini_set("display_errors", "1");
$pageToLoad = $_POST['load'];
function get_data($url) {
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt ($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
$html = get_data($pageToLoad);
$newHtml = preg_match("~<body[^>]*>(.*?)</body>~si", $html, $newHtml);
print_r($newHtml);
?>
答案 0 :(得分:0)
最简单的方法是使用像这样的正则表达式:
preg_match('|body[^>]*>(.*?)(?=\</body)|si',$html,$match);
echo $match[1];
您希望使用正则表达式的S和I修饰符来跨越多行并且不区分大小写。
答案 1 :(得分:0)
当您尝试将属性作为搜索模式的一部分时,尝试在html中查找模式可能是一个冒险的命题。例如,属性值可以是单引号或双引号,并且即使有人忘记引用某些内容或引号不匹配,大多数解析器也能够管理。由于您只是在寻找特定的属性名称,因此它更容易,但仍然存在问题,例如您要查找的属性名称是否作为另一个属性中的值存在。
(哎呀,你的原始简单正则表达式会错误地匹配一些不太可能的字符串,如<bodycustomelement>...</body>
。
由于样式属性几乎总是后跟一个等号,我将使用该事实来查找它。我还要确保我匹配一个身体元素,而不是像上面例子那样的一些不可能的突变体。
<body\s[^>]*style\s*=[^>]*>(.*?)</body>
这与原始正则表达式基本相同,但在其中间有\s[^>]*style\s*=
。
\s
确保body元素后面有空格,以便它只能是body元素。[^>]*
匹配任何字符,但>
0次或更多次style
匹配字符串“style”\s*
允许样式和等号之间的空格=
匹配字符串“=”我很难想到一个会破坏这个正则表达式的例子,这也不会导致解析器出现问题。我想如果有人在元素开头的<
和body
之间添加了空格,或者在body
的结尾处有空格或任何其他字符。有人可能只是一起省略了关闭体元素。
你可以继续添加到正则表达式来处理这些例子,但是对于你在野外会遇到的任何情况,我给出的都可以正常工作。