我正在构建一个应该像这样解析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];
}
答案 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