PHP Regex匹配<;车身样式=>;并且</身体>;标签


PHP Regex to match everything between <body style=...> and </body> tag

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

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

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

由于style属性后面几乎总是跟一个等号,我会用这个事实来找到它。我还会确保我匹配一个body元素,而不是像上面的例子那样的不太可能的变体。

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

这基本上与原始regex相同,但中间有's[^>]*style's*=

  1. CCD_ 7确保在主体元素之后存在空间,使得它只能是主体元素
  2. [^>]*匹配除>以外的任何字符0次或更多次
  3. style匹配字符串"style"
  4. 's*允许样式和等号之间有空白
  5. =与字符串"="匹配

我很难想出一个例子来混淆这个正则表达式,它不会导致解析器出现问题。我想,如果有人在元素的开头在<body之间添加了空格,或者他们在body的结尾有空格或任何其他字符。另外,有些人可能会把封闭体元素全部省略掉。

您可以不断添加到regex中来处理这些示例,但对于您在野外遇到的任何情况,我给出的都会很好地工作。

最简单的方法是使用类似以下的正则表达式:

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

您希望对Regex使用S和I修饰符来跨越多行并且不区分大小写。