【问题标题】:PHP Regex to get youtube video ID?PHP Regex 获取 youtube 视频 ID?
【发布时间】:2011-03-24 12:11:12
【问题描述】:

有人可以告诉我如何从 url 中获取 youtube id,而不管 URL 中还有哪些其他 GET 变量。

以该视频为例:http://www.youtube.com/watch?v=C4kxS1ksqtw&feature=related
所以在v= 和下一个& 之前

【问题讨论】:

  • 这可能会有所帮助stackoverflow.com/questions/9522868/…
  • 你应该看看我的代码github.com/lingtalfi/video-ids-and-thumbnails/blob/master/…,我提供了从youtube、vimeo和dailymotion中提取id的函数。
  • @ling 在函数 getVideoThumbnailByUrl() 中您使用的是 Vimeo 已弃用的 file_get_contents()。这种替换适用于任何地方:$ch=curl_init(); curl_setopt($ch, CURLOPT_URL, "http://vimeo.com/api/v2/video/$id.php"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); $hash =unserialize(curl_exec($ch)); curl_close($ch);
  • @ling 同样在 getYoutubeId($url) 中,最终条件将接受任何字符串并将其验证为 YT id。我将它传递给“垃圾”,它返回垃圾作为从该字符串解析的 id。
  • @jerrygarciuh:afaik file_get_contents 未被弃用,如果您对此功能有疑问,请随时在 github 上报告问题。感谢您发现 getYoutubeId 中的错误(我对其进行了增强)。

标签: php regex


【解决方案1】:

基于 bokor 对 Anthony 回答的评论:

preg_match("/^(?:http(?:s)?:\/\/)?(?:www\.)?(?:m\.)?(?:youtu\.be\/|youtube\.com\/(?:(?:watch)?\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user|shorts)\/))([^\?&\"'>]+)/", $url, $matches);

$matches[1] 包含 vidid

匹配:

不匹配:

【讨论】:

  • 你有这个字符串的 C/objc/c++ 版本吗?我不知道要逃脱哪些部分。
  • 我试过了:“^(?:http(?:s)?://)?(?:www\\.)?(?:youtu\\.be/|youtube\\ .com/(?:(?:watch)?\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)/))([^\? &\"'>]+)" 没有通过你所有的例子
  • 我发现了我的问题。这是最后的 c 字符串:"^(?:http(?:s)?://)?(?:www\\.)?(?:youtu\\.be/|youtube\\.com/ (?:(?:watch)?\\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)/))([^\?&\ "'>]+)"
  • 还要考虑像youtube.com/watch?v=vidid#action=share 这样的网址,我已将# 添加到结束捕获组:preg_match("/^(?:http(?:s)?:\/\/)?(?:www\.)?(?:m\.)?(?:youtu\.be\/|youtube\.com\/(?:(?:watch)?\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)\/))([^\?#&\"'>]+)/", $url, $matches);
  • 它在页面上添加带有空格的内容并抓取页面上 url 之后的所有文本。这样更好 /(?:http(?:s)?:\/\/)?(?:www\.)?(?:m\.)?(?:youtu\.be\/|youtube\. com\/(?:(?:watch)?\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)\/))([a- zA-Z0-9\-_]*)/
【解决方案2】:

使用此代码:

$url = "http://www.youtube.com/watch?v=C4kxS1ksqtw&feature=related"; 
$parse = parse_url($url, PHP_URL_QUERY); 
parse_str($parse, $output); 
echo $output['watch'];

结果:C4kxS1ksqtw

【讨论】:

    【解决方案3】:

    为了在捕获组中提取id,以下表达式或其派生词也可能是一种选择:

    (?im)\b(?:https?:\/\/)?(?:w{3}\.)?youtu(?:be)?\.(?:com|be)\/(?:(?:\??v=?i?=?\/?)|watch\?vi?=|watch\?.*?&v=|embed\/|)([A-Z0-9_-]{11})\S*(?=\s|$)
    

    Demo

    测试

    $re = '/(?im)\b(?:https?:\/\/)?(?:w{3}\.)?youtu(?:be)?\.(?:com|be)\/(?:(?:\??v=?i?=?\/?)|watch\?vi?=|watch\?.*?&v=|embed\/|)([A-Z0-9_-]{11})\S*(?=\s|$)/';
    $str = 'http://youtube.com/v/tFad5gHoBjY
    https://youtube.com/vi/tFad5gHoBjY
    http://www.youtube.com/?v=tFad5gHoBjY
    http://www.youtube.com/?vi=tFad5gHoBjY
    https://www.youtube.com/watch?v=tFad5gHoBjY
    youtube.com/watch?vi=tFad5gHoBjY
    youtu.be/tFad5gHoBjY
    http://youtu.be/qokEYBNWA_0?t=30m26s
    youtube.com/v/7HCZvhRAk-M
    youtube.com/vi/7HCZvhRAk-M
    youtube.com/?v=7HCZvhRAk-M
    youtube.com/?vi=7HCZvhRAk-M
    youtube.com/watch?v=7HCZvhRAk-M
    youtube.com/watch?vi=7HCZvhRAk-M
    youtu.be/7HCZvhRAk-M
    youtube.com/embed/7HCZvhRAk-M
    http://youtube.com/v/7HCZvhRAk-M
    http://www.youtube.com/v/7HCZvhRAk-M
    https://www.youtube.com/v/7HCZvhRAk-M
    youtube.com/watch?v=7HCZvhRAk-M&wtv=wtv
    http://www.youtube.com/watch?dev=inprogress&v=7HCZvhRAk-M&feature=related
    youtube.com/watch?v=7HCZvhRAk-M
    http://youtube.com/v/dQw4w9WgXcQ?feature=youtube_gdata_player
    http://youtube.com/vi/dQw4w9WgXcQ?feature=youtube_gdata_player
    http://youtube.com/?v=dQw4w9WgXcQ&feature=youtube_gdata_player
    http://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=youtube_gdata_player
    http://youtube.com/?vi=dQw4w9WgXcQ&feature=youtube_gdata_player
    http://youtube.com/watch?v=dQw4w9WgXcQ&feature=youtube_gdata_player
    http://youtube.com/watch?vi=dQw4w9WgXcQ&feature=youtube_gdata_player
    http://youtu.be/dQw4w9WgXcQ?feature=youtube_gdata_player';
    
    preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
    
    var_dump($matches);
    

    输出

    array(30) {
      [0]=>
      array(2) {
        [0]=>
        string(32) "http://youtube.com/v/tFad5gHoBjY"
        [1]=>
        string(11) "tFad5gHoBjY"
      }
      [1]=>
      array(2) {
        [0]=>
        string(34) "https://youtube.com/vi/tFad5gHoBjY"
        [1]=>
        string(11) "tFad5gHoBjY"
      }
      [2]=>
      array(2) {
        [0]=>
        string(37) "http://www.youtube.com/?v=tFad5gHoBjY"
        [1]=>
        string(11) "tFad5gHoBjY"
      }
      [3]=>
      array(2) {
        [0]=>
        string(38) "http://www.youtube.com/?vi=tFad5gHoBjY"
        [1]=>
        string(11) "tFad5gHoBjY"
      }
      [4]=>
      array(2) {
        [0]=>
        string(43) "https://www.youtube.com/watch?v=tFad5gHoBjY"
        [1]=>
        string(11) "tFad5gHoBjY"
      }
      [5]=>
      array(2) {
        [0]=>
        string(32) "youtube.com/watch?vi=tFad5gHoBjY"
        [1]=>
        string(11) "tFad5gHoBjY"
      }
      [6]=>
      array(2) {
        [0]=>
        string(20) "youtu.be/tFad5gHoBjY"
        [1]=>
        string(11) "tFad5gHoBjY"
      }
      [7]=>
      array(2) {
        [0]=>
        string(27) "http://youtu.be/qokEYBNWA_0"
        [1]=>
        string(11) "qokEYBNWA_0"
      }
      [8]=>
      array(2) {
        [0]=>
        string(25) "youtube.com/v/7HCZvhRAk-M"
        [1]=>
        string(11) "7HCZvhRAk-M"
      }
      [9]=>
      array(2) {
        [0]=>
        string(26) "youtube.com/vi/7HCZvhRAk-M"
        [1]=>
        string(11) "7HCZvhRAk-M"
      }
      [10]=>
      array(2) {
        [0]=>
        string(26) "youtube.com/?v=7HCZvhRAk-M"
        [1]=>
        string(11) "7HCZvhRAk-M"
      }
      [11]=>
      array(2) {
        [0]=>
        string(27) "youtube.com/?vi=7HCZvhRAk-M"
        [1]=>
        string(11) "7HCZvhRAk-M"
      }
      [12]=>
      array(2) {
        [0]=>
        string(31) "youtube.com/watch?v=7HCZvhRAk-M"
        [1]=>
        string(11) "7HCZvhRAk-M"
      }
      [13]=>
      array(2) {
        [0]=>
        string(32) "youtube.com/watch?vi=7HCZvhRAk-M"
        [1]=>
        string(11) "7HCZvhRAk-M"
      }
      [14]=>
      array(2) {
        [0]=>
        string(20) "youtu.be/7HCZvhRAk-M"
        [1]=>
        string(11) "7HCZvhRAk-M"
      }
      [15]=>
      array(2) {
        [0]=>
        string(29) "youtube.com/embed/7HCZvhRAk-M"
        [1]=>
        string(11) "7HCZvhRAk-M"
      }
      [16]=>
      array(2) {
        [0]=>
        string(32) "http://youtube.com/v/7HCZvhRAk-M"
        [1]=>
        string(11) "7HCZvhRAk-M"
      }
      [17]=>
      array(2) {
        [0]=>
        string(36) "http://www.youtube.com/v/7HCZvhRAk-M"
        [1]=>
        string(11) "7HCZvhRAk-M"
      }
      [18]=>
      array(2) {
        [0]=>
        string(37) "https://www.youtube.com/v/7HCZvhRAk-M"
        [1]=>
        string(11) "7HCZvhRAk-M"
      }
      [19]=>
      array(2) {
        [0]=>
        string(31) "youtube.com/watch?v=7HCZvhRAk-M"
        [1]=>
        string(11) "7HCZvhRAk-M"
      }
      [20]=>
      array(2) {
        [0]=>
        string(57) "http://www.youtube.com/watch?dev=inprogress&v=7HCZvhRAk-M"
        [1]=>
        string(11) "7HCZvhRAk-M"
      }
      [21]=>
      array(2) {
        [0]=>
        string(31) "youtube.com/watch?v=7HCZvhRAk-M"
        [1]=>
        string(11) "7HCZvhRAk-M"
      }
      [22]=>
      array(2) {
        [0]=>
        string(32) "http://youtube.com/v/dQw4w9WgXcQ"
        [1]=>
        string(11) "dQw4w9WgXcQ"
      }
      [23]=>
      array(2) {
        [0]=>
        string(33) "http://youtube.com/vi/dQw4w9WgXcQ"
        [1]=>
        string(11) "dQw4w9WgXcQ"
      }
      [24]=>
      array(2) {
        [0]=>
        string(33) "http://youtube.com/?v=dQw4w9WgXcQ"
        [1]=>
        string(11) "dQw4w9WgXcQ"
      }
      [25]=>
      array(2) {
        [0]=>
        string(42) "http://www.youtube.com/watch?v=dQw4w9WgXcQ"
        [1]=>
        string(11) "dQw4w9WgXcQ"
      }
      [26]=>
      array(2) {
        [0]=>
        string(34) "http://youtube.com/?vi=dQw4w9WgXcQ"
        [1]=>
        string(11) "dQw4w9WgXcQ"
      }
      [27]=>
      array(2) {
        [0]=>
        string(38) "http://youtube.com/watch?v=dQw4w9WgXcQ"
        [1]=>
        string(11) "dQw4w9WgXcQ"
      }
      [28]=>
      array(2) {
        [0]=>
        string(39) "http://youtube.com/watch?vi=dQw4w9WgXcQ"
        [1]=>
        string(11) "dQw4w9WgXcQ"
      }
      [29]=>
      array(2) {
        [0]=>
        string(27) "http://youtu.be/dQw4w9WgXcQ"
        [1]=>
        string(11) "dQw4w9WgXcQ"
      }
    }
    

    如果您希望简化/修改/探索表达式,请在regex101.com 的右上角面板中进行说明。如果您愿意,您还可以在this link 中观看它如何与一些示例输入匹配。


    正则表达式电路

    jex.im 可视化正则表达式:


    【讨论】:

      【解决方案4】:

      如果我想从一个充满其他字符的字符串中提取一个 YouTube 网址怎么办?像这样:

      Lorem ipsum dolor sit amet,consectetur adipiscing elit,sed do eiusmod tempor incididunt ut labore et dolore magna aliqua。 Ut enim ad minim veniam, quis nostrud exercitation ullamco https://www.youtube.com/watch?v=cPW9Y94BJI0 laboris nisi ut aliquip ex ea commodo consequat。 Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur。 Exceptioneur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum。

      并从该字符串中获取https://www.youtube.com/watch?v=cPW9Y94BJI0

      【讨论】:

        【解决方案5】:

        以下内容适用于所有 youtube 链接

        <?php
            // Here is a sample of the URLs this regex matches: (there can be more content after the given URL that will be ignored)
            // http://youtu.be/dQw4w9WgXcQ
            // http://www.youtube.com/embed/dQw4w9WgXcQ
            // http://www.youtube.com/watch?v=dQw4w9WgXcQ
            // http://www.youtube.com/?v=dQw4w9WgXcQ
            // http://www.youtube.com/v/dQw4w9WgXcQ
            // http://www.youtube.com/e/dQw4w9WgXcQ
            // http://www.youtube.com/user/username#p/u/11/dQw4w9WgXcQ
            // http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/0/dQw4w9WgXcQ
            // http://www.youtube.com/watch?feature=player_embedded&v=dQw4w9WgXcQ
            // http://www.youtube.com/?feature=player_embedded&v=dQw4w9WgXcQ
            // It also works on the youtube-nocookie.com URL with the same above options.
            // It will also pull the ID from the URL in an embed code (both iframe and object tags)
        
        $url = "https://www.youtube.com/watch?v=v2_MLFVdlQM";
        
            preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $url, $match);
        
            $youtube_id = $match[1];
        
        echo $youtube_id;
            ?>
        

        【讨论】:

          【解决方案6】:

          我认为您正在尝试这样做。

          <?php
            $video = 'https://www.youtube.com/watch?v=u00FY9vADfQ';
            $parsed_video = parse_url($video, PHP_URL_QUERY);
            parse_str($parsed_video, $arr);
          ?>
          <iframe
          src="https://www.youtube.com/embed/<?php echo $arr['v'];  ?>"
          frameborder="0">
          </iframe>
          

          【讨论】:

            【解决方案7】:

            我使用了来自Shawn's answer 的数据,但稍微概括和缩短了正则表达式。与这个的主要区别在于它不会测试有效的 Youtube URL,它只会查找视频 ID。这意味着它仍会返回 www.facebook.com?wtv=youtube.com/v/vidid 的视频 ID。适用于所有测试用例,但有点松懈。因此,它将为https://www.twitter.com/watch?v=vidid 之类的内容输出误报。如果数据超级不一致就用这个方法,否则用更具体的正则表达式或者parse_url()parse_str()

            preg_match("/([\?&\/]vi?|embed|\.be)[\/=]([\w-]+)/",$url,$matches);
            print($matches[2]);
            

            【讨论】:

              【解决方案8】:

              基于How to validate youtube video ids?修复

              <?php
              
              $links = [
                  "youtube.com/v/tFad5gHoBjY",
                  "youtube.com/vi/tFad5gHoBjY",
                  "youtube.com/?v=tFad5gHoBjY",
                  "youtube.com/?vi=tFad5gHoBjY",
                  "youtube.com/watch?v=tFad5gHoBjY",
                  "youtube.com/watch?vi=tFad5gHoBjY",
                  "youtu.be/tFad5gHoBjY",
                  "http://youtu.be/qokEYBNWA_0?t=30m26s",
                  "youtube.com/v/vidid",
                  "youtube.com/vi/vidid",
                  "youtube.com/?v=vidid",
                  "youtube.com/?vi=vidid",
                  "youtube.com/watch?v=vidid",
                  "youtube.com/watch?vi=vidid",
                  "youtu.be/vidid",
                  "youtube.com/embed/vidid",
                  "http://youtube.com/v/vidid",
                  "http://www.youtube.com/v/vidid",
                  "https://www.youtube.com/v/vidid",
                  "youtube.com/watch?v=vidid&wtv=wtv",
                  "http://www.youtube.com/watch?dev=inprogress&v=vidid&feature=related",
                  "youtube.com/watch?v=7HCZvhRAk-M"
              ];
              
              foreach($links as $link){
                  preg_match("#([\/|\?|&]vi?[\/|=]|youtu\.be\/|embed\/)([a-zA-Z0-9_-]+)#", $link, $matches);
                  var_dump(end($matches));
              }
              

              【讨论】:

                【解决方案9】:

                刚刚在http://snipplr.com/view/62238/get-youtube-video-id-very-robust/在线找到这个

                function getYouTubeId($url) {
                // Format all domains to http://domain for easier URL parsing
                str_replace('https://', 'http://', $url);
                if (!stristr($url, 'http://') && (strlen($url) != 11)) {
                    $url = 'http://' . $url;
                }
                $url = str_replace('http://www.', 'http://', $url);
                
                if (strlen($url) == 11) {
                    $code = $url;
                } else if (preg_match('/http:\/\/youtu.be/', $url)) {
                    $url = parse_url($url, PHP_URL_PATH);
                    $code = substr($url, 1, 11);
                } else if (preg_match('/watch/', $url)) {
                    $arr = parse_url($url);
                    parse_str($url);
                    $code = isset($v) ? substr($v, 0, 11) : false;
                } else if (preg_match('/http:\/\/youtube.com\/v/', $url)) {
                    $url = parse_url($url, PHP_URL_PATH);
                    $code = substr($url, 3, 11);
                } else if (preg_match('/http:\/\/youtube.com\/embed/', $url, $matches)) {
                    $url = parse_url($url, PHP_URL_PATH);
                    $code = substr($url, 7, 11);
                } else if (preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]/)[^&\n]+|(?<=v=)[^&\n]+#", $url, $matches) ) {
                    $code = substr($matches[0], 0, 11);
                } else {
                    $code = false;
                }
                
                if ($code && (strlen($code) < 11)) {
                    $code = false;
                }
                
                return $code;
                }
                

                【讨论】:

                  【解决方案10】:

                  解决方案适用于任何链接类型!!

                  <?php
                  function get_youtube_id_from_url($url)  {
                       preg_match('/(http(s|):|)\/\/(www\.|)yout(.*?)\/(embed\/|watch.*?v=|)([a-z_A-Z0-9\-]{11})/i', $url, $results);    return $results[6];
                  }
                  
                  
                  echo get_youtube_id_from_url('http://www.youtube.com/watch?var1=blabla#v=GvJehZx3eQ1$var2=bla');
                        // or                   http://youtu.be/GvJehZx3eQ1 
                        // or                   http://www.youtube.com/embed/GvJehZx3eQ1
                        // or                   http://www.youtu.be/GvJehZx3eQ1/blabla?xyz
                  ?>
                  

                  输出: GvJehZx3eQ1

                  【讨论】:

                  • 小心使用它来匹配任何 YT URL:https://www.youtube.com/watch?v=9E6F57s-V7U&amp;ab_channel=Accent%27sWayEnglishwithHadar $results[0] 形式的链接将不包含完整链接,仅包含视频 ID 之前的部分。 This helped.
                  【解决方案11】:

                  这可以很容易地使用parse_strparse_url 完成,并且在我看来更可靠。

                  我的函数支持以下网址:

                  还包括函数下面的测试。

                  /**
                   * Get Youtube video ID from URL
                   *
                   * @param string $url
                   * @return mixed Youtube video ID or FALSE if not found
                   */
                  function getYoutubeIdFromUrl($url) {
                      $parts = parse_url($url);
                      if(isset($parts['query'])){
                          parse_str($parts['query'], $qs);
                          if(isset($qs['v'])){
                              return $qs['v'];
                          }else if(isset($qs['vi'])){
                              return $qs['vi'];
                          }
                      }
                      if(isset($parts['path'])){
                          $path = explode('/', trim($parts['path'], '/'));
                          return $path[count($path)-1];
                      }
                      return false;
                  }
                  // Test
                  $urls = array(
                      'http://youtube.com/v/dQw4w9WgXcQ?feature=youtube_gdata_player',
                      'http://youtube.com/vi/dQw4w9WgXcQ?feature=youtube_gdata_player',
                      'http://youtube.com/?v=dQw4w9WgXcQ&feature=youtube_gdata_player',
                      'http://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=youtube_gdata_player',
                      'http://youtube.com/?vi=dQw4w9WgXcQ&feature=youtube_gdata_player',
                      'http://youtube.com/watch?v=dQw4w9WgXcQ&feature=youtube_gdata_player',
                      'http://youtube.com/watch?vi=dQw4w9WgXcQ&feature=youtube_gdata_player',
                      'http://youtu.be/dQw4w9WgXcQ?feature=youtube_gdata_player'
                  );
                  foreach($urls as $url){
                      echo $url . ' : ' . getYoutubeIdFromUrl($url) . "\n";
                  }
                  

                  【讨论】:

                  • 这真的很棒,实际上也适用于 vimeo 视频
                  • 这也是我的首选答案。它确实涵盖了 YouTube 和 Vimeo。请注意,我确实添加了一个额外的 isset() 的超级小调整 - else if(isset($qs['vi']))。非常感谢。
                  【解决方案12】:

                  我们知道视频 ID 的长度为 11 个字符,并且可以在前面加上 v=vi=v/vi/youtu.be/。所以最简单的方法是:

                  <?php
                  $youtube = 'http://youtube.com/v/dQw4w9WgXcQ?feature=youtube_gdata_player
                  http://youtube.com/vi/dQw4w9WgXcQ?feature=youtube_gdata_player
                  http://youtube.com/?v=dQw4w9WgXcQ&feature=youtube_gdata_player
                  http://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=youtube_gdata_player
                  http://youtube.com/?vi=dQw4w9WgXcQ&feature=youtube_gdata_player
                  http://youtube.com/watch?v=dQw4w9WgXcQ&feature=youtube_gdata_player
                  http://youtube.com/watch?vi=dQw4w9WgXcQ&feature=youtube_gdata_player
                  http://youtu.be/dQw4w9WgXcQ?feature=youtube_gdata_player';
                  
                  preg_match_all("#(?<=v=|v\/|vi=|vi\/|youtu.be\/)[a-zA-Z0-9_-]{11}#", $youtube, $matches);
                  
                  var_dump($matches[0]);
                  

                  然后输出:

                  array(8) {
                    [0]=>
                    string(11) "dQw4w9WgXcQ"
                    [1]=>
                    string(11) "dQw4w9WgXcQ"
                    [2]=>
                    string(11) "dQw4w9WgXcQ"
                    [3]=>
                    string(11) "dQw4w9WgXcQ"
                    [4]=>
                    string(11) "dQw4w9WgXcQ"
                    [5]=>
                    string(11) "dQw4w9WgXcQ"
                    [6]=>
                    string(11) "dQw4w9WgXcQ"
                    [7]=>
                    string(11) "dQw4w9WgXcQ"
                  }
                  

                  【讨论】:

                    【解决方案13】:

                    我知道线程的标题是指使用正则表达式,但正如 Zawinski 引用所说,我真的认为最好避免使用正则表达式。我会推荐这个功能:

                    function get_youtube_id($url)
                    {
                        if (strpos( $url,"v=") !== false)
                        {
                            return substr($url, strpos($url, "v=") + 2, 11);
                        }
                        elseif(strpos( $url,"embed/") !== false)
                        {
                            return substr($url, strpos($url, "embed/") + 6, 11);
                        }
                    
                    }
                    

                    我建议这样做,因为 YouTube 视频的 ID 始终相同,与 URL 的样式无关,例如

                    • http://www.youtube.com/watch?v=t_uW44Bsezg
                    • http://www.youtube.com/watch?feature=endscreen&amp;v=Id3xG4xnOfA&amp;NR=1
                    • `和其他 Ulr 形式,其中单词“embed/”放置在 Id 之前...!!

                    这可能是嵌入式和iframe-ed 的情况。

                    【讨论】:

                      【解决方案14】:

                      我必须对一些帖子内容进行加密,才能从中获取 Youtube ID。它恰好是 Youtube 提供的 &lt;iframe&gt; 嵌入代码的形式。

                       <iframe src="http://www.youtube.com/embed/Zpk8pMz_Kgw?rel=0" frameborder="0" width="620" height="360"></iframe>
                      

                      我从上面的@rob 得到的以下模式。一旦找到匹配项,sn-p 就会执行foreach 循环,为了获得额外的奖励,我将其链接到在 Youtube 上找到的预览图像。它可能会匹配更多类型的 Youtube 嵌入类型和 url:

                      $pattern = '#(?<=(?:v|i)=)[a-zA-Z0-9-]+(?=&)|(?<=(?:v|i)\/)[^&\n]+|(?<=embed\/)[^"&\n]+|(?<=‌​(?:v|i)=)[^&\n]+|(?<=youtu.be\/)[^&\n]+#';
                      
                      preg_match_all($pattern, $post_content, $matches);
                      
                      foreach ($matches as $match) {
                          $img = "<img src='http://img.youtube.com/vi/".str_replace('?rel=0','', $match[0])."/0.jpg' />";
                          break;
                      }
                      

                      Rob 的个人资料:https://stackoverflow.com/users/149615/rob

                      【讨论】:

                        【解决方案15】:
                        preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=v\/)[^&\n]+|(?<=v=)[^&\n]+|(?<=youtu.be/)[^&\n]+#", $url, $matches);
                        

                        这将占

                        youtube.com/v/{vidid}
                        youtube.com/vi/{vidid}
                        youtube.com/?v={vidid}
                        youtube.com/?vi={vidid}
                        youtube.com/watch?v={vidid}
                        youtube.com/watch?vi={vidid}
                        youtu.be/{vidid}
                        

                        我稍微改进了它以支持: http://www.youtube.com/v/5xADESocujo?feature=autoshare&version=3&autohide=1&autoplay=1

                        我现在使用的行是:

                        preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=v\/)[^&\n]+(?=\?)|(?<=v=)[^&\n]+|(?<=youtu.be/)[^&\n]+#", $link, $matches);
                        

                        【讨论】:

                        • 我已经对其进行了更新,使其也可以处理这样的 URL:youtube.com/embed/7zuAOomfiCc#(?&lt;=v=)[a-zA-Z0-9-]+(?=&amp;)|(?&lt;=v\/)[^&amp;\n]+(?=\?)|(?&lt;=embed/)[^&amp;\n]+|(?&lt;=v=)[^&amp;\n]+|(?&lt;=youtu.be/)[^&amp;\n]+#
                        • 这适用于所有网址,包括嵌入字符串(?&lt;=(?:v|i)=)[a-zA-Z0-9-]+(?=&amp;)|(?&lt;=(?:v|i)\/)[^&amp;\n]+|(?&lt;=embed\/)[^"&amp;\n]+|(?&lt;=(?:v|i)=)[^&amp;\n]+|(?&lt;=youtu.be\/)[^&amp;\n]+rubular.com/r/M9PJYcQxRW
                        • 这个怎么样 /(youtu\.be\/|youtube\.com\/(watch\?(.*&)?v=|(embed|v|user)\/)) ([^\?&"'>]+)/
                        • 实际上@bokor 的代码用更多信息填充了$matches 数组,包括对我的项目非常有用的视频ID
                        • 除了 Rob 的正则表达式,&list 也被捕获。这在下面的正则表达式中被删除:#(?youtu.be/RRyG_mtYieI?list=PLnBXpb1YLPttKF7RZX64qI_AEyFjTvgtxyoutube.com/…‌​_AEyFjTvgtx //www.youtube.com/embed/RRyG_mtYieI?list=PLnBXpb1YLPttKF7RZX64qI_AEyFjTvgtx youtube.com/v/RRyG_mtYieI
                        【解决方案16】:

                        Use parse_url()parse_str()

                        (您几乎可以将正则表达式用于任何事情,但它们很容易出错,因此如果有专门用于您想要完成的 PHP 函数,请使用它们。)

                        parse_url 接受一个字符串并将其分割成一个包含大量信息的数组。您可以使用此数组,也可以将所需的一项指定为第二个参数。在这种情况下,我们对查询感兴趣,即PHP_URL_QUERY

                        现在我们有了查询,即v=C4kxS1ksqtw&amp;feature=relate,但我们只想要v= 之后的部分。为此,我们转向parse_str,它基本上像GET 一样在字符串上工作。它接受一个字符串并创建字符串中指定的变量。在这种情况下,$v$feature 被创建。我们只对$v感兴趣。

                        为了安全起见,您不想将来自parse_url 的所有变量都存储在您的命名空间中(请参阅mellowsoon 的评论)。而是将变量存储为数组的元素,这样您就可以控制要存储的变量,并且不会意外覆盖现有变量。

                        把所有东西放在一起,我们有:

                        <?php
                        $url = "http://www.youtube.com/watch?v=C4kxS1ksqtw&feature=relate";
                        parse_str( parse_url( $url, PHP_URL_QUERY ), $my_array_of_vars );
                        echo $my_array_of_vars['v'];    
                          // Output: C4kxS1ksqtw
                        ?> 
                        

                        Working example


                        编辑:

                        呵呵 - 谢谢查尔斯。这让我发笑,我以前从未见过 Zawinski 的名言:

                        Some people, when confronted with a problem, think ‘I know, I’ll use regular expressions.’ Now they have two problems.杰米·扎温斯基

                        【讨论】:

                        • 虽然它不使用正则表达式(至少明显 - 我不确定 parse_url() 是如何工作的),但这是要走的路。
                        • 。尽管严肃地说,使用语言函数来执行任务通常比一个好的正则表达式可能需要的箍跳更好。
                        • 我只建议使用 parse_str() 的第二个参数将查询参数存储在一个数组中。让变量神奇地凭空出现绝不是一个好主意。
                        • 一个简单的例子说明为什么使用 parse_str() 的“魔术变量”不是一个好主意 -> pastebin.com/AtaaPH4r
                        • @Qualcuno - 当然不是。这专门用于检索“获取变量” - 根据 OP。您的示例不是获取变量。
                        【解决方案17】:
                        $vid = preg_replace('/^.*(\?|\&)v\=/', '', $url);  // Strip all meuk before and including '?v=' or '&v='.
                        
                        $vid = preg_replace('/[^\w\-\_].*$/', '', $vid);  // Strip trailing meuk.
                        

                        【讨论】:

                          【解决方案18】:
                          (?<=\?v=)([a-zA-Z0-9_-]){11}
                          

                          这也应该这样做。

                          【讨论】:

                            【解决方案19】:
                            if (preg_match('![?&]{1}v=([^&]+)!', $url . '&', $m))
                                $video_id = $m[1];
                            

                            【讨论】:

                            • 谢谢,这对我很有用,因为我想要所有域,http 和 https,以及 url 中的任何其他垃圾。
                            猜你喜欢
                            • 2012-04-15
                            • 2021-02-10
                            • 2012-09-08
                            • 2016-04-22
                            • 2012-03-24
                            • 2020-11-05
                            • 2011-11-05
                            • 1970-01-01
                            • 2016-09-28
                            相关资源
                            最近更新 更多