解析文本中的 bbcode youtube 标签并替换为包含视频 ID 的 html

发布于 2024-07-22 19:11:27 字数 1272 浏览 7 评论 0 原文

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

输入:
输出:

<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() (或 split)时,永远找不到分隔符。 即使使用“u”或“tube”等测试值......

function processYouTubeVideos ($str) {

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

    return $params[0];

}

I'm building a blog that should parse bbcode tags like this:

Input: <youtube=http://www.youtube.com/watch?v=VIDEO_ID&feature=channel>
Output:

<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>

My function is incredibly simple so far, because I've gotten stuck on the easiest part! Right now, I have a master process function that calls difference process functions. In this case one of them is processYouTubeVideos(). So I call it like so:

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

processYouTubeVideos() receives the URLs from inside the youtube tag perfectly, but for some reason, when using explode() (or split) the delimiter is never found. Even using test values like "u" or "tube"...

function processYouTubeVideos ($str) {

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

    return $params[0];

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

温柔戏命师 2024-07-29 19:11:31

之前的两个答案现在都已被彻底弃用。

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

该模式本身不会花费很大的努力来验证 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

Both of the earlier answers are now well and truly deprecated.

The modern technique is to use preg_replace_callback(), then parse the url and isolate the targeted portion of the query string. I'll demonstrate using sprintf() with placeholders in the html template string.

The pattern itself doesn't go to any great effort to validate the bbcode tag, so if you need strong validation, the pattern will need refinement.

Code: (Demo)

$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
     );

Output:

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
羞稚 2024-07-29 19:11:28

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

我认为以下内容符合您的意图:

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

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

The processYouTubeVideos("\1") function is being run before the eregi_replace.

The following does what I believe you intend:

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

It performs the replace, and then sends the resulting value to processYouTubeVideos.

迷路的信 2024-07-29 19:11:27

尝试:

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

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

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

Try:

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

The code that you're attempting to run won't work, because the function on the output string will be called on the target pattern rather than the output. That means that you're sending "\1" literarly to the function. Add var_dump($str); to the beginning of the function and try running your code again, and you'll see this clearly.

preg_replace has a special flag "e" that you can use to execute a function for each time a replacement is made. This works by inserting the subpattern at the marker position ($1) and then running something like eval() or create_function() on the code to execute it and retrieve the result. This then sent back to preg_replace() and the actual replacement is made.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文