YouTube 视频和短裤 id 的 Javascript 正则表达式

我想从 YouTube 的视频 url 返回视频 ID,即使是 Shorts

但我有一些适用于一些不包括短裤的网址的模式

^.*((youtu.be/)|(v/)|(/u/w/)|(embed/)|(watch?))??v?=?([^#&?]*).*

编辑: 它应该适用于以下网址:

http://www.youtube.com/watch?v=0zM3nApSvMg&feature=feedrec_grec_index
http://www.youtube.com/user/IngridMichaelsonVEVO#p/a/u/1/QdK8U-VIH_o
http://www.youtube.com/v/0zM3nApSvMg?fs=1&hl=en_US&rel=0
http://www.youtube.com/watch?v=0zM3nApSvMg#t=0m10s
http://www.youtube.com/embed/0zM3nApSvMg?rel=0
http://www.youtube.com/watch?v=0zM3nApSvMg
http://youtu.be/0zM3nApSvMg
https://youtube.com/shorts/0dPkkQeRwTI?feature=share
https://youtube.com/shorts/0dPkkQeRwTI

谢谢你

stack overflow Javascript Regex for YouTube video and shorts id
原文答案
author avatar

接受的答案

这应该适用于提供的示例

(youtu.*be.*)/(watch?v=|embed/|v|shorts|)(.*?((?=[&#?])|$))

https://regex101.com/r/5JhmpW/1 实际视频 id 应该是每场比赛中的第三个捕获组。

  • Group1: Url 直到最后一部分
  • Group2:接收videoId作为参数的url的最后一部分
  • Group3:网址的最后一部分(即“/v/”、“/embed/”、“/user/”、“/shorts/”和“youtu.be/”变体中的videoId),或 videoId 参数(在手表的情况下)

你可以像这样在javascript中使用它:

let data = `http://www.youtube.com/watch?v=0zM3nApSvMg&feature=feedrec_grec_index
http://www.youtube.com/user/IngridMichaelsonVEVO#p/a/u/1/QdK8U-VIH_o
http://www.youtube.com/v/0zM3nApSvMg?fs=1&hl=en_US&rel=0
http://www.youtube.com/watch?v=0zM3nApSvMg#t=0m10s
http://www.youtube.com/embed/0zM3nApSvMg?rel=0
http://www.youtube.com/watch?v=0zM3nApSvMg
http://youtu.be/0zM3nApSvMg
https://youtube.com/shorts/0dPkkQeRwTI?feature=share
https://youtube.com/shorts/0dPkkQeRwTI`;
let regex = /(youtu.*be.*)/(watch?v=|embed/|v|shorts|)(.*?((?=[&#?])|$))/gm;
let videoIds = [...data.matchAll(regex)].map(x => x[3]);

或者,如果您一次只期望一个网址:

function getVideoId(url) {
    let regex = /(youtu.*be.*)/(watch?v=|embed/|v|shorts|)(.*?((?=[&#?])|$))/gm;
    return regex.exec(url)[3];
}

请记住 javascript 中的正则表达式不是无状态的,多次运行相同的正则表达式将导致它遍历文本中的匹配项(一旦到达末尾最终返回 NULL),这就是重新初始化正则表达式的原因在这种情况下,每次通话。如果没有找到匹配项,它也将返回 null。


答案:

作者头像

一次获取 1 个预期 URL 的正则表达式,捕获可通过 named groups MDN 访问的 id 组。

^(?:(?:https|http)://)?(?:www.)?(?:youtube.com|youtu.be).*(?<=/|v/|u/|embed/|shorts/|watch?v=)(?<!/user/)(?<id>[w-]{11})(?=?|&|$)

由于我需要返回 ID 或 false,这就是我编写函数的方式:

function youtubeLinkToEmbed(link) {
    const youtubeIdRegex =
        /^(?:(?:https|http)://)?(?:www.)?(?:youtube.com|youtu.be).*(?<=/|v/|u/|embed/|shorts/|watch?v=)(?<!/user/)(?<id>[w-]{11})(?=?|&|$)/;

    return link.match(youtubeIdRegex)?.groups?.id || false;
}

UPD:自 10.2022 起,Safari/Webkit 不再支持 lookbehind 语法,因此使用上述方法可能会破坏您的 Web 应用程序。

我将在下面留下我为向后兼容 Webkit 而制作的逻辑和丑陋的正则表达式。

function stripYoutubeId(link) {
    if (!link) {
        return false;
    }

    const youtubeIdRegex =
        /^(?:(?:https|http)://)?(?:www.)?(?:youtube.com|youtu.be).*?(?:/|v/|u/|embed/|shorts/|watch?v=|(?<username>user/))(?<id>[w-]{11})(?:?|&|$)/;

    const match = link.match(youtubeIdRegex);

    // checks if 'user/' is located right before expected id, in which case it would return username instead
    if (match?.groups?.username || !match?.groups?.id) {
        return false;
    }

    return `https://www.youtube.com/embed/${match.groups.id}`;
}