Php:在字符串中查找第一个img或object标签

时间:2009-07-24 05:24:28

标签: php regex wordpress

我想问一下我在这段代码中犯的错误。 我目前正在尝试找到第一次出现的图像标签或对象标签然后返回一段html,如果它匹配一个。 目前,我可以获取图片标签,但遗憾的是我似乎无法在对象标签上获得任何结果。

我想,我在我的正则表达式模式中做了一些错误。希望要求足够清楚,让您理解感谢。

我的代码在这里:

  function get_first_image(){
      global $post, $posts;
      $first_img = '';
      ob_start();
      ob_end_clean();
      $output = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches) || preg_match_all('/<object[0-9 a-z_?*=\":\-\/\.#\,<>\\n\\r\\t]+<\/object>/smi', $post->post_content, $matches);
      $first_img = $matches [1] [0];

      if(empty($first_img)){ //Defines a default image
        $mediaSearch = preg_match_all('/<object[0-9 a-z_?*=\":\-\/\.#\,<>\\n\\r\\t]+<\/object>/smi', $post->post_content, $matches2);
        $first_media = $matches2 [1] [0];
        $first_img = "/images/default.jpg";
      }

      if(!empty($first_img)){
        $result = "<div class=\"alignleft\"><img src=\"$first_img\" style=\"max-width: 200px;\" /></div>";
      }

      if(!empty($first_media)){
        $result = "<p>" . $first_media . "</p>";
      }

      return $result;
    }

2 个答案:

答案 0 :(得分:3)

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

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

function get_first_image(){
    global $post, $posts;

    require_once('SimpleHTML.class.php')

    $post_dom = str_get_dom($post->post_content);

    $first_img = $post_dom->find('img', 0);

    if($first_img !== null) {
        $first_img->style = $first_img->style . ';max-width: 200px';
        return '<div class="alignleft">' . $first_img->outertext . '</div>';
    } else {
        $first_obj = $post_dom->find('object', 0);

        if($first_obj !== null) {
            return '<p>' . $first_obj->outertext . '</p>';
        }
    }

    return '<div class="alignleft"><img src="/images/default.jpg" style="max-width: 200px;" /></div>';
}

有些人可能认为这样做有点过分,但最终,维护起来会更容易,并且还可以提供更多的可扩展性。例如,使用DOM解析器,我可以添加到当前图像的样式。

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

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

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

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

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

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

答案 1 :(得分:2)

试试这个:(你需要在匹配数组中定义你想要的东西)

function get_first_image(){
      global $post, $posts;
      $first_img = '';
      ob_start();
      ob_end_clean();
      $output = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches) || preg_match_all('(/<object[0-9 a-z_?*=\":\-\/\.#\,<>\\n\\r\\t]+<\/object>)/smi', $post->post_content, $matches);
      $first_img = $matches [1] [0];

      if(empty($first_img)){ //Defines a default image
        $mediaSearch = preg_match_all('/<object[0-9 a-z_?*=\":\-\/\.#\,<>\\n\\r\\t]+<\/object>/smi', $post->post_content, $matches2);
        $first_media = $matches2 [1] [0];
        $first_img = "/images/default.jpg";
      }

      if(!empty($first_img)){
        $result = "<div class=\"alignleft\"><img src=\"$first_img\" style=\"max-width: 200px;\" /></div>";
      }

      if(!empty($first_media)){
        $result = "<p>" . $first_media . "</p>";
      }

      return $result;
    }