PHP Regex匹配和标记之间的所有内容

时间:2014-11-04 12:54:36

标签: php html regex curl match

我有一个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);
?>

2 个答案:

答案 0 :(得分:0)

最简单的方法是使用像这样的正则表达式:

preg_match('|body[^>]*>(.*?)(?=\</body)|si',$html,$match); 

echo $match[1]; 

您希望使用正则表达式的S和I修饰符来跨越多行并且不区分大小写。

答案 1 :(得分:0)

当您尝试将属性作为搜索模式的一部分时,尝试在html中查找模式可能是一个冒险的命题。例如,属性值可以是单引号或双引号,并且即使有人忘记引用某些内容或引号不匹配,大多数解析器也能够管理。由于您只是在寻找特定的属性名称,因此它更容易,但仍然存在问题,例如您要查找的属性名称是否作为另一个属性中的值存在。

(哎呀,你的原始简单正则表达式会错误地匹配一些不太可能的字符串,如<bodycustomelement>...</body>

由于样式属性几乎总是后跟一个等号,我将使用该事实来查找它。我还要确保我匹配一个身体元素,而不是像上面例子那样的一些不可能的突变体。

<body\s[^>]*style\s*=[^>]*>(.*?)</body>

REY

这与原始正则表达式基本相同,但在其中间有\s[^>]*style\s*=

  1. \s确保body元素后面有空格,以便它只能是body元素。
  2. [^>]*匹配任何字符,但> 0次或更多次
  3. style匹配字符串“style”
  4. \s*允许样式和等号之间的空格
  5. =匹配字符串“=”
  6. 我很难想到一个会破坏这个正则表达式的例子,这也不会导致解析器出现问题。我想如果有人在元素开头的<body之间添加了空格,或者在body的结尾处有空格或任何其他字符。有人可能只是一起省略了关闭体元素。

    你可以继续添加到正则表达式来处理这些例子,但是对于你在野外会遇到的任何情况,我给出的都可以正常工作。