PHP explode()没有找到分隔符

时间:2009-05-25 21:52:35

标签: php parsing bbcode

我正在构建一个应该像这样解析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标记内部接收网址,但出于某种原因,当使用explode()(或拆分)时,永远不会找到分隔符。甚至使用“u”或“tube”等测试值......

function processYouTubeVideos ($str) {

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

    return $params[0];

}

3 个答案:

答案 0 :(得分:3)

尝试:

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

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

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

答案 1 :(得分:0)

在 eregi_replace之前正在运行进程youTubeVideos(“\ 1”)。

以下是我认为您的意图:

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

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

答案 2 :(得分:0)

之前的两个答案现在都已完全弃用。

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

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

代码:(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
     );

输出:

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