3

所以,我基本上是在尝试匹配对象标签内(包括)的任何内容,如下所示:

<?php preg_match_all('/<object(.*)<\/object>/', $blah, $blahBlah); ?>

它为此找到匹配项:

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="250" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://vimeo.com/moogaloop.swf?clip_id=9048799&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed type="application/x-shockwave-flash" width="400" height="250" src="http://vimeo.com/moogaloop.swf?clip_id=9048799&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" allowscriptaccess="always" allowfullscreen="true"></embed></object>

但它不会匹配这个:

<object width="400" height="300"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=5630744&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=5630744&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"></embed></object>

知道为什么吗?感谢您的任何见解。


ETA:由于我的方法一开始可能有问题,这里有一些关于我正在尝试做的事情的背景。

这是一个 Wordpress 网站。我正在使用一个将短标签转换为完整视频嵌入代码的插件。该插件最近(谢天谢地)更新以使代码更有效。

我正在尝试创建的功能只是在帖子中找到第一个视频对象,然后将其抓取以在网站的其他地方使用。

这是整个函数(其中一些只有在您使用过 Wordpress 时才有意义):

<?php
function catch_that_video() {
  global $post, $posts;
  $the_video = '';
  ob_start();
  ob_end_clean();
  $output = preg_match_all('/<object(.*)<\/object>/', $post->post_content, $vid_matches);
  $the_video = $vid_matches [1] [0];
  if(empty($the_video)){ $the_video = 0; }
  return $the_video;
}
?>
4

2 回答 2

1

唯一想到的是单行与多行。

/<object(.*)<\/object>/m

这应该匹配多行。

本手册页讨论了修饰符:

http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php

更新:

经过进一步调查,m不是正确的修饰符(来自手册):

m (PCRE_MULTILINE) 默认情况下,PCRE 将主题字符串视为由单个“行”字符组成(即使它实际上包含多个换行符)。“行首”元字符 (^) 仅匹配字符串的开头,而“行尾”元字符 ($) 仅匹配字符串末尾或终止换行符之前(除非设置了 D 修饰符)。这与 Perl 相同。 设置此修饰符后,“行首”和“行尾”构造分别匹配主题字符串中任何换行符之后或之前的任何换行符,以及开头和结尾处。这相当于 Perl 的 /m 修饰符。如果主题字符串中没有“\n”字符,或者模式中没有出现 ^ 或 $,则设置此修饰符无效。

(强调我自己的。)

正确的修饰符是s允许点元字符.匹配换行符。

继续讨论更新后的问题,如果这些输入是简单字符串,则正则表达式本身匹配这两个输入。我不知道是什么导致了实际问题。

$input = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="250" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://vimeo.com/moogaloop.swf?clip_id=9048799&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed type="application/x-shockwave-flash" width="400" height="250" src="http://vimeo.com/moogaloop.swf?clip_id=9048799&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" allowscriptaccess="always" allowfullscreen="true"></embed></object>';

$input2 = '<object width="400" height="300"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=5630744&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=5630744&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"></embed></object>';

$matches = array();
preg_match_all('/<object(.*)<\/object>/', $input, $matches); 
echo '<br />$input<pre>';
var_dump($matches);
echo '</pre>';

$matches2 = array();
preg_match_all('/<object(.*)<\/object>/', $input2, $matches2); 
echo '<br />$input2<pre>';
var_dump($matches2);
echo '</pre>';

继续:

你想用这两条线来完成什么?

ob_start();
ob_end_clean();

这会打开一个新的输出缓冲区并立即将其杀死。(请参阅文档中有关堆叠输出缓冲区的内容。)

是否有理由将其设置为 0,而不是说null

if(empty($the_video)){ $the_video = 0; }

就个人而言,我会null在声明它时将其设置为,并且如果没有匹配项,则依赖于不破坏它。这就是我编写该函数的方式,假设它$post是一个 WordPress 全局函数。(就个人而言,我只是将它传递给函数,因为我不屑于大多数全局变量。)

function catch_that_video() 
{
  global $post;

  $the_video = null;
  $vid_matches = array();

  if(preg_match('/<object.*<\/object>/', $post->post_content, $vid_matches))
  {
    $the_video = $vid_matches[0];
  }

  return $the_video;
}

我将其更改为使用preg_match而不是preg_match_all,因为您仅使用第一个匹配项。当然,preg_match_all如有必要,可以将其修改为使用 。但是,创建适当的正则表达式会很痛苦。(将s修饰符添加到上述正则表达式以处理多行将获取从第一个开始<object>标记到最后一个结束</object>标记的所有内容。我什至不想考虑尝试提出一个正则表达式来覆盖多行和抓住单个<object>...</object>块。)

但是,这并不能回答关于为什么第二个对象块不匹配的原始问题。我会将我的调查重点放在试图发现两个字符串之间的区别上。如果问题是行尾之间的区别,我会在 Linux 上使用 VIM 之类的东西,因为它会显示 `^M' 代替行尾中的 \r。字符串的html编码怎么样?这可能是一个可能的问题吗?

于 2010-07-17T02:13:28.857 回答
0

这个 ..

 ob_start();
 ob_end_clean();

..应该看起来像这样..


  ob_get_level() 
    and ob_end_clean();

于 2022-02-05T21:42:19.010 回答