2

我正在构建一个应该解析 bbcode 标签的博客,如下所示:

输入:<youtube=http://www.youtube.com/watch?v=VIDEO_ID&feature=channel>
输出:

<object width="400" height="245">
<param name="movie" value="http://www.youtube-    nocookie.com/v/VIDEO_ID&hl=en&fs=1&rel=0&showinfo=0"></param>
<param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param>
<embed src="http://www.youtube-nocookie.com/v/VIDEO_ID&hl=en&fs=1&rel=0&showinfo=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="400" height="245"></embed>
</object>

到目前为止,我的功能非常简单,因为我已经陷入了最简单的部分!现在,我有一个主进程函数,它调用不同的进程函数。在这种情况下,其中之一是 processYouTubeVideos()。所以我这样称呼它:

$str = eregi_replace('\<youtube=([^>]*)\>', processYouTubeVideos("\\1"), $str);

processYouTubeVideos() 完美地接收来自 youtube 标记内部的 URL,但由于某种原因,当使用 explode() (或拆分)时,永远找不到分隔符。即使使用“u”或“tube”之类的测试值......

function processYouTubeVideos ($str) {

    $params = explode("?", $str);
    $params = explode("&", $params[1]);

    return $params[0];

}
4

3 回答 3

3

尝试:

$str = preg_replace('/<youtube=([^>]*)>/e', 'processYouTubeVideos("$1")', $str);

您尝试运行的代码将不起作用,因为输出字符串上的函数将在目标模式而不是输出上调用。这意味着您要按字面意思向函数发送“\1”。添加var_dump($str);到函数的开头并尝试再次运行您的代码,您会清楚地看到这一点。

preg_replace有一个特殊的标志“e”,您可以使用它在每次替换时执行一个函数。这通过在标记位置 ($1) 插入子模式,然后在代码上运行类似eval()or的东西create_function()来执行它并检索结果来工作。然后将其发送回preg_replace()并进行实际替换。

于 2009-05-25T21:57:51.237 回答
0

processYouTubeVideos("\1") 函数在 eregi_replace之前运行。

以下是我相信你想要的:

$str = eregi_replace('\<youtube=([^>]*)\>', "\\1", $str);
$str = processYouTubeVideos($str);

它执行替换,然后将结果值发送到 processYouTubeVideos。

于 2009-05-25T22:05:20.783 回答
0

早期的两个答案现在都已被完全弃用。

现代技术是使用preg_replace_callback(),然后解析 url 并隔离查询字符串的目标部分。我将演示sprintf()在 html 模板字符串中使用占位符。

模式本身并没有花太多精力来验证 bbcode 标记,因此如果您需要强验证,则需要对模式进行改进。

代码:(演示

$bbCode = <<<BBCODE
Here is some text <youtube=http://www.youtube.com/watch?v=VIDEO_ID&feature=channel> and some more text
BBCODE;

echo preg_replace_callback(
         '~<youtube=([^>]+)>~',
         function ($m) {
             parse_str(parse_url($m[1], PHP_URL_QUERY), $queryStringArray);
             $videoId = $queryStringArray['v'] ?? null;
             if (!$videoId) {
                 return $m[0];  // do not replace bbcode because could not isolate the video id
             }
             return sprintf(
                        '<object width="400" height="245">
                             <param name="movie" value="http://www.youtube-nocookie.com/v/%1$s&hl=en&fs=1&rel=0&showinfo=0"></param>
                             <param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param>
                             <embed src="http://www.youtube-nocookie.com/v/%1$s&hl=en&fs=1&rel=0&showinfo=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="400" height="245"></embed>
                         </object>',
                         $videoId
                    );
         },
         $bbCode
     );

输出:

Here is some text <object width="400" height="245">
                             <param name="movie" value="http://www.youtube-nocookie.com/v/VIDEO_ID&hl=en&fs=1&rel=0&showinfo=0"></param>
                             <param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param>
                             <embed src="http://www.youtube-nocookie.com/v/VIDEO_ID&hl=en&fs=1&rel=0&showinfo=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="400" height="245"></embed>
                         </object> and some more text
于 2021-03-19T05:53:47.607 回答