You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将preg_replace匹配变量$2传入getYoutubeVideoID函数

问题解决:PHP中preg_replace捕获组无法传入自定义函数的问题

问题场景

现有两个PHP函数:bbc2html用于将BBCode转换为HTML,getYoutubeVideoID用于从YouTube链接中提取视频ID。在处理[youtube]标签时,尝试将preg_replace匹配到的链接(捕获组$2)传入getYoutubeVideoID,但实际传入的是字符串'$2',无法得到正确的视频ID。

原函数代码:

function bbc2html($content) {
    $search = array (
      '/(\[b\])(.*?)(\[\/b\])/',
      '/(\[u\])(.*?)(\[\/u\])/',
      '/(\[i\])(.*?)(\[\/i\])/',
      '/(\[youtube\])(.*?)(\[\/youtube\])/'
    );
  
    $replace = array (
      '<b>$2</b>',
      '<u>$2</u>',
      '<i>$2</i>',
      '<div class="video_wrapper card border-0 shadow text-center m-2" style="width: 25rem;">
       <div class="video_trigger card-body" data-source="'.getYoutubeVideoID('$2').'" data-type="youtube">
          <p class="text-center">As soon as you click on the button you accept that cookies from YouTube to be loaded</p>
          <input type="button" class="btn btn-success" value="OK">
          <a href="$2" type="button" target="_blank" class="btn btn-danger"><i class="fa-brands fa-youtube pe-1"></i>direct link</a>
       </div>
       <div class="video_layer" style="display: none;">
          <iframe src="" border="0" data-scaling="true" data-format="16:9" style="height: 0px;"></iframe>
       </div>
       </div>'
    );
    
    return preg_replace($search, $replace , $content);
  }
function getYoutubeVideoID($link):string{
    $baseUrl = parse_url($link, PHP_URL_HOST); 

    if($baseUrl == "youtu.be"){
        $urlParts = explode('/',$link);
        $id = end($urlParts);
    } elseif (preg_match('/(youtube.com)/i',$baseUrl)) {
        if(preg_match('/(youtube.com\/watch\?v=)/i',$link)){
            $urlParts = explode('?v=',$link);
            $id = end($urlParts);
        } elseif(preg_match('/(youtube.com\/)/i',$link)) {
            $urlParts = explode('/',$link);
            $id = end($urlParts);
        } else {
            return "";
        }
    } else {
        return "";
    }

    return $id;
}

解决方法

preg_replace的替换字符串无法直接执行函数处理捕获组内容,需要改用preg_replace_callback,通过回调函数处理每个匹配结果,再调用getYoutubeVideoID获取真实视频ID。

修改后的bbc2html函数:

function bbc2html($content) {
    // 先处理粗体、下划线、斜体这些简单替换
    $content = preg_replace('/\[b\](.*?)\[\/b\]/', '<b>$1</b>', $content);
    $content = preg_replace('/\[u\](.*?)\[\/u\]/', '<u>$1</u>', $content);
    $content = preg_replace('/\[i\](.*?)\[\/i\]/', '<i>$1</i>', $content);
    
    // 处理youtube标签,用回调函数处理捕获组
    $content = preg_replace_callback('/\[youtube\](.*?)\[\/youtube\]/', function($matches) {
        // $matches[1]是匹配到的YouTube链接
        $videoId = getYoutubeVideoID($matches[1]);
        // 返回拼接好的HTML结构
        return '<div class="video_wrapper card border-0 shadow text-center m-2" style="width: 25rem;">
           <div class="video_trigger card-body" data-source="' . $videoId . '" data-type="youtube">
              <p class="text-center">点击按钮即表示您同意加载YouTube的Cookie</p>
              <input type="button" class="btn btn-success" value="确定">
              <a href="' . $matches[1] . '" type="button" target="_blank" class="btn btn-danger"><i class="fa-brands fa-youtube pe-1"></i>直接链接</a>
           </div>
           <div class="video_layer" style="display: none;">
              <iframe src="" border="0" data-scaling="true" data-format="16:9" style="height: 0px;"></iframe>
           </div>
           </div>';
    }, $content);
    
    return $content;
}

说明

  1. 简单的BBCode(粗体、下划线、斜体)仍用preg_replace处理,保持简洁。
  2. YouTube标签改用preg_replace_callback,回调函数的$matches参数包含所有捕获组内容,$matches[1]就是匹配到的视频链接,直接传入getYoutubeVideoID即可得到正确的视频ID。
  3. 同时将提示文本翻译成了中文,符合国内使用场景。

内容的提问来源于stack exchange,提问作者Heisenberg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 02:30:43