YouTube视频ID的正则表达式

34

我已经搜索了很多地方,看到了许多解析YouTube视频ID的方式,但是它们都没有匹配所有可能出现的各种格式的YouTube URL。我尝试了之前文章中提供的正则表达式,但是没有任何一种方法能够奏效。

我发现最接近覆盖所有URL格式的文章是这篇:使用正则表达式在字符串中查找所有YouTube视频ID的方法是什么?

然而,这并不适用于以下情况: http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/0/FJUvudQsKCM

我是在 JavaScript 中进行操作的。有人可以帮忙吗?!

提前致谢。

当前URL格式和我正在使用的脚本:

var url = "http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/0/FJUvudQsKCM";
//var url = "http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo";
//var url = "http://youtu.be/NLqAF9hrVbY";
//var url = "http://www.youtube.com/embed/NLqAF9hrVbY";
//var url = "https://www.youtube.com/embed/NLqAF9hrVbY";
//var url = "http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US";
//var url = "http://www.youtube.com/watch?v=NLqAF9hrVbY";
//var url = "http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo";
//var url = "http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I";
//var url = "http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo";
//var url = "http://www.youtube.com/watch?v=JYArUl0TzhA&feature=featured";

var videoID = url.match(/(?:youtu\.be\/|youtube\.com(?:\/embed\/|\/v\/|\/watch\?v=|\/user\/\S+|\/ytscreeningroom\?v=))([\w\-]{10,12})\b/)[1];
alert(videoID);

你可以尝试使用 get-video-id。它可以从任何已知的Youtube URL字符串(或嵌入字符串)中获取ID。 - radiovisual
在这种情况下,我会使用另一个实用程序来读取URL参数并跟踪v。为了保证正确性,在此之后删除所有URL参数,然后测试此正则表达式:([\w\d_-]+)$/ gim https://regexr.com/566ho - user11736763
7个回答

73

这是一个重复的问题,在此之前已经得到了回答。

我认为你会发现那里的正则表达式在这里也适用。

使用preg_match解析YouTube视频ID

编辑: 我注意到它不能处理你列表顶部的sandalsResort URL,所以你可以修改正则表达式为以下内容(转换为JS使用)。

var myregexp = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/gi;
我所做的只是将user 替换为 [^/]+
ID 仍在后向引用 1 中被捕获。

1
谢谢... 是的,正如我所提到的,我找到了很多不同的正则表达式,但是它们都没有涵盖所有可能的URL情况。这个很好用! - Stanley
我在使用这个正则表达式从HTML中解析YouTube链接时遇到了一些问题,所以我稍微更新了它:/(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*?[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/gi - derekantrican
如果这是一个重复的问题,为什么不关闭它? - Toto
3
因为我并不太在意?当我9年前回答这个问题时,我没有足够的分数来关闭它。 - Benjam
2
如果您需要“-nocookie”选项,请使用以下正则表达式: /(?:youtube(?:-nocookie)?.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu.be/)([^"&?/\s]{11})/gi; - N Djel Okoye
显示剩余2条评论

7

我使用这个正则表达式:/youtu(?:.*\/v\/|.*v\=|\.be\/)([A-Za-z0-9_\-]{11})/,它对我来说工作得很好。


4

要处理所有可能的URL,编写一个正则表达式会非常混乱。

我可能会使用if ... else if ... else结构来确定URL的形式,然后使用更小、更具体的正则表达式来提取每个视频ID。


这正是get-video-id中发生的情况。 - radiovisual

3
您可能不需要使用正则表达式来完成此任务。该模式变化很小,定界符本身(/,有时还包括 ?=#)是固定的。我建议您采取以下步骤,使用普通的字符串操作来决定下一步操作:
  1. / 上分割 URL。
  2. 忽略 http://www.(如果存在)。
  3. 检查域名是否为 youtube.comyoutu.be
  4. 如果 DN 是 youtu.be,则 ID 是下一个片段。返回它并停止。
  5. 开始解析参数。检查下一个片段:
    • 如果是 embed,则完整返回下一个片段。
    • 如果是 v,则按 ? 分割并返回第一部分。
    • 如果是 user,则计算前进四个片段,即可获得 ID。
    • 如果是 watch,则先按 ? 分割,然后再按 = 分割。

...等等。

我不知道 YouTube URL 可能有多少种模式,但如果您有完整的格式列表,可以简单地在它们周围构建 if/else 树。我的主要建议是仅在 / 上分割并从那里开始,使用 URL 中的上下文提示来确定如何解析其余部分。


这基本上就是 get-video-id 中正在发生的事情。它不会尝试维护一个适用于所有内容的单个 RegExp,而是将 URL 模式分成组,这使得推理变得更加容易。 - radiovisual

2

试试这个:

var urls = 
["http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/0/FJUvudQsKCM",
"http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo",
"http://youtu.be/NLqAF9hrVbY",
"http://www.youtube.com/embed/NLqAF9hrVbY",
"https://www.youtube.com/embed/NLqAF9hrVbY",
"http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US",
"http://www.youtube.com/watch?v=NLqAF9hrVbY",
"http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo",
"http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I",
"http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo",
"http://www.youtube.com/watch?v=JYArUl0TzhA&feature=featured"];

var ids = []; 

for(var i in urls) {
    tmp = urls [ i ];
    tmp2 = get_video_id(tmp);
    if(tmp2 != null)
    {
        ids.push("url:" + tmp + " ID:" + tmp2);
    }
}

alert(ids.join("\n"));



function get_video_id(input) {
return input.match(/(?:youtu\.be\/|youtube\.com(?:\/embed\/|\/v\/|\/watch\?v=|\/user\/\S+|\/ytscreeningroom\?v=|\/sandalsResorts#\w\/\w\/.*\/))([^\/&]{10,12})/)[1]; 
}

输出:

url:http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/0/FJUvudQsKCM ID:FJUvudQsKCM
url:http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo ID:p3vcRhsYGo
url:http://youtu.be/NLqAF9hrVbY ID:NLqAF9hrVbY
url:http://www.youtube.com/embed/NLqAF9hrVbY ID:NLqAF9hrVbY
url:https://www.youtube.com/embed/NLqAF9hrVbY ID:NLqAF9hrVbY
url:http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US ID:NLqAF9hrVbY?
url:http://www.youtube.com/watch?v=NLqAF9hrVbY ID:NLqAF9hrVbY
url:http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo ID:p3vcRhsYGo
url:http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I ID:NRHVzbJVx8I
url:http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo ID:p3vcRhsYGo
url:http://www.youtube.com/watch?v=JYArUl0TzhA&feature=featured ID:JYArUl0TzhA

1
我认为问题在于“sandalsResort”部分可能不是静态的,并且对于具有相同格式的不同URL将会发生变化。 - Benjam
1
Scobleizer URL的ID缺少一个字符。 - Daniel Wood

0
var get_id = function(url){
    var code = url.match(/v=([^&#]{5,})/)
    return (typeof code[1] == 'string') ? code[1] : false;
}

-2

将你的正则表达式融入到这个示例中:

(是否有一种方法可以从文本中获取一个数组(带有多个YouTube视频?)

复制并粘贴到名为detectYoutubeLinksAsYouType.html的文件中

附言:是只有我吗...还是stackoverflow.com的登录功能完全是胡说八道...

<!DOCTYPE HTML>
<html>
    <head>
        <title></title>

        <!-- scripts -->
        <!-- last jquery version that supports ie8/9 -->
        <script type="text/javascript" src="../js/jquery-1.10.2.js"></script>
        <script type="text/javascript">
            /* search for youtube-video-id inside a given text / url */
            function findYoutubeVideoID(url) {

                // thanks for the regexes guys!
                var YoutubeRegexObject_v1 = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/i; // only gets the first VideoURL
                var YoutubeRegexObject_v2 = /(?:youtu\.be\/|youtube\.com(?:\/embed\/|\/v\/|\/watch\?v=|\/user\/\S+|\/ytscreeningroom\?v=|\/sandalsResorts#\w\/\w\/.*\/))([^\/&]{10,12})/;

                var YoutubeVideoID = url.match(YoutubeRegexObject_v1);

                return YoutubeVideoID[1];
            }

            /* generate youtube embed code */
            function generateYoutubeEmbedCode(YoutubeVideoID,width,height)
            {
                if(!width)
                {
                    width = "854";
                }
                if(!height)
                {
                    height = "510";
                }
                return '<iframe width="'+width+'" height="'+height+'" src="//www.youtube.com/embed/'+YoutubeVideoID+'" frameborder="0" allowfullscreen></iframe>';
            }

            $(document).ready(function() {
                $("#text").on('change keyup paste', function() {
                    var text = $(this).html();
                    var YoutubeVideoID = findYoutubeVideoID(text);
                    var YoutubeVideoEmbedCode = generateYoutubeEmbedCode(YoutubeVideoID);
                    $("#findYoutubeVideoID").html(YoutubeVideoID);
                    $("#DisplayVideo").html(YoutubeVideoEmbedCode);
                });

                $("#search").on('click', function() {
                    var text = $("#text").html();
                    var YoutubeVideoID = findYoutubeVideoID(text);
                    var YoutubeVideoEmbedCode = generateYoutubeEmbedCode(YoutubeVideoID);
                    $("#findYoutubeVideoID").html(YoutubeVideoID);
                    $("#DisplayVideo").html(YoutubeVideoEmbedCode);
                });
            });
        </script>
    </head>
    <body>
        <style>
            .parent {
                margin: 0 auto;
                position: relative;
                border: 1px solid red;
                width: 500px;
            }
            .element {
                border: 1px solid red;
                position: relative;
                float: left;
                min-height: 20px;
                margin: 10px;
                min-width: 45%;
            }
        </style>
        <div class="parent">
            <div class="element">Detect youtube links as you type!</div>
            <div class="element" id="text" contenteditable="true">
                Copy paste Youtube-Video-Url here! e.g. this one: https://www.youtube.com/watch?v=QOJ1nYPBonQ
            </div>
            <div class="element" >The VideoID is:</div>
            <div class="element" id="findYoutubeVideoID"></div>
            <div class="element" id="DisplayVideo"></div>
            <div class="element"> <button id="search">Search for YoutubeID</button></div>
        </div>
    </body>
</html>

为什么我已经登录了还需要输入验证码? - canoodle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接