18

我制作了一个函数(在 JavaScript 中),它从 YouTube 或 Vimeo 获取 URL。它计算出该特定视频的提供者和 ID(演示:http: //jsfiddle.net/csjwf/)。

function parseVideoURL(url) {

    var provider = url.match(/http:\/\/(:?www.)?(\w*)/)[2],
        id;

    if(provider == "youtube") {

        id = url.match(/http:\/\/(?:www.)?(\w*).com\/.*v=(\w*)/)[2];
    } else if (provider == "vimeo") {

        id = url.match(/http:\/\/(?:www.)?(\w*).com\/(\d*)/)[2];
    } else {
        throw new Error("parseVideoURL() takes a YouTube or Vimeo URL");    
    }
    return {
        provider : provider,
        id : id
    }
}

它可以工作,但是作为一个正则表达式新手,我正在寻找改进它的方法。我正在处理的输入通常如下所示:

http://vimeo.com/(id)
http://youtube.com/watch?v=(id)&blahblahblah.....

1)现在我正在做三场单独的比赛,尝试在一个表达式中完成所有事情是否有意义?如果是这样,怎么做?

2)现有的匹配可以更简洁吗?它们是否不必要地复杂?或者可能不够?

3) 是否有任何无法解析的 YouTube 或 Vimeo URL?我已经尝试了很多,到目前为止它似乎工作得很好。

总结一下:我只是在寻找改进上述功能的方法。任何意见是极大的赞赏。

4

11 回答 11

24

这是我对正则表达式的尝试,它涵盖了最新的案例:

function parseVideo(url) {
    // - Supported YouTube URL formats:
    //   - http://www.youtube.com/watch?v=My2FRPA3Gf8
    //   - http://youtu.be/My2FRPA3Gf8
    //   - https://youtube.googleapis.com/v/My2FRPA3Gf8
    // - Supported Vimeo URL formats:
    //   - http://vimeo.com/25451551
    //   - http://player.vimeo.com/video/25451551
    // - Also supports relative URLs:
    //   - //player.vimeo.com/video/25451551

    url.match(/(https?\/\/)(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);
    var type = null;
    if (RegExp.$3.indexOf('youtu') > -1) {
        type = 'youtube';
    } else if (RegExp.$3.indexOf('vimeo') > -1) {
        type = 'vimeo';
    }

    return {
        type: type,
        id: RegExp.$6
    };
}
于 2014-03-31T14:14:05.987 回答
15

正则表达式非常简洁,但很快就会变得复杂。

http://jsfiddle.net/8nagx2sk/

function parseYouTube(str) {
    // link : //youtube.com/watch?v=Bo_deCOd1HU
    // share : //youtu.be/Bo_deCOd1HU
    // embed : //youtube.com/embed/Bo_deCOd1HU

    var re = /\/\/(?:www\.)?youtu(?:\.be|be\.com)\/(?:watch\?v=|embed\/)?([a-z0-9_\-]+)/i; 
    var matches = re.exec(str);
    return matches && matches[1];
}

function parseVimeo(str) {
    // embed & link: http://vimeo.com/86164897

    var re = /\/\/(?:www\.)?vimeo.com\/([0-9a-z\-_]+)/i;
    var matches = re.exec(str);
    return matches && matches[1];
}

有时,简单的代码对您的开发人员来说更好。

https://jsfiddle.net/vkg02mhp/1/

// protocol and www nuetral
function getVideoId(str, prefixes) {
  const cleaned = str.replace(/^(https?:)?\/\/(www\.)?/, '');
  for(const prefix of prefixes) {
    if (cleaned.startsWith(prefix))
      return cleaned.substr(prefix.length)
  }
  return undefined;
}

function getYouTubeId(url) {
  return getVideoId(url, [
    'youtube.com/watch?v=',
    'youtu.be/',
    'youtube.com/embed/'
  ]);
}

function getVimeoId(url) {
  return getVideoId(url, [
    'vimeo.com/'
  ]);
}

你更喜欢更新哪个?

于 2014-02-12T18:07:27.743 回答
11

我不确定您的问题 3),但是如果您对 url 表单的归纳是正确的,则可以将正则表达式组合成一个,如下所示:

/http:\/\/(?:www.)?(?:(vimeo).com\/(.*)|(youtube).com\/watch\?v=(.*?)&)/

您将在不同的位置获得比赛(如果是 vimeo,则为第 1 场和第 2 场比赛,如果是 youtube,则为第 3 场和第 4 场比赛),因此您只需要处理即可。

或者,如果你很确定 vimeo 的 id 只包含数字,那么你可以这样做:

/http:\/\/(?:www.)?(vimeo|youtube).com\/(?:watch\?v=)?(.*?)(?:\z|&)/

并且提供者和 id 将分别出现在第 1 场和第 2 场比赛中。

于 2011-04-10T17:15:15.987 回答
7

这是我的正则表达式

http://jsfiddle.net/csjwf/1/

于 2011-04-10T17:41:41.853 回答
7

对于 Vimeo,不要依赖Regex,因为 Vimeo 往往会不时更改/更新其 URL 模式。截至2017 年 10 月 2 日,Vimeo 总共支持六种 URL 方案。

https://vimeo.com/*
https://vimeo.com/*/*/video/*
https://vimeo.com/album/*/video/*
https://vimeo.com/channels/*/*
https://vimeo.com/groups/*/videos/*
https://vimeo.com/ondemand/*/*

相反,使用他们的 API 来验证 vimeo URL。这是这个 oEmbed ( doc ) API,它接受一个 URL,检查其有效性并返回一个包含大量视频信息的对象(查看开发页面)。虽然不是有意的,但我们可以轻松地使用它来验证给定的 URL 是否来自 Vimeo。

所以,使用 ajax 看起来像这样,

var VIMEO_BASE_URL = "https://vimeo.com/api/oembed.json?url=";
var yourTestUrl = "https://vimeo.com/23374724";


$.ajax({
  url: VIMEO_BASE_URL + yourTestUrl,
  type: 'GET',
  success: function(data) {
    if (data != null && data.video_id > 0)
      // Valid Vimeo url
    else
      // not a valid Vimeo url
  },
  error: function(data) {
    // not a valid Vimeo url
  }
});
于 2017-10-02T12:33:19.983 回答
6

关于sawa的回答:

第二个正则表达式的一些更新:

/http:\/\/(?:www\.)?(vimeo|youtube)\.com\/(?:watch\?v=)?(.*?)(?:\z|$|&)/

(转义点会阻止匹配 www_vimeo_com/... 类型的 url 并添加 $...)

这是匹配嵌入网址的相同想法:

/http:\/\/(?:www\.|player\.)?(vimeo|youtube)\.com\/(?:embed\/|video\/)?(.*?)(?:\z|$|\?)/
于 2011-12-19T18:52:25.090 回答
2

FWIW,我只是使用以下内容来验证和解析应用程序中的 YouTube 和 Vimeo URL。我相信您可以添加括号来解析您正在寻找的特定内容......

/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$|^(https?:\/\/)?(www.)?(player.)?vimeo.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*$/

^^ 这只是使用|(或)连接它们的 2 个单独表达式的组合。这里分别是原始的 2 个表达式:

/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/

/^(https?:\/\/)?(www.)?(player.)?vimeo.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*$/

我不是专家,但它似乎根据 Rubular 工作。希望这可以帮助将来的人。

于 2020-08-18T20:20:56.683 回答
1

3)您的正则表达式与 https 网址不匹配。我还没有测试过,但我猜“http://”部分会变成“http(s)?://”。请注意,这将更改提供者和 id 的匹配位置。

于 2014-04-04T12:50:14.747 回答
1

我的任务是启用添加保管箱视频。所以同样的输入应该采用href,检查它并转换为我可以插入的可播放链接。

const getPlayableUrl = (url) => {
    // Check youtube and vimeo
    let firstCheck = url.match(/(http:|https:|)\/\/(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);

    if (firstCheck) {
        if (RegExp.$3.indexOf('youtu') > -1) {
            return "//www.youtube.com/embed/" + RegExp.$6;
        } else if (RegExp.$3.indexOf('vimeo') > -1) {
            return 'https://player.vimeo.com/video/' + RegExp.$6
        }
    } else {
        // Check dropbox
        let candidate = ''
        if (url.indexOf('.mp4') !== -1) {
            candidate = url.slice(0, url.indexOf('.mp4') + 4)
        } else if (url.indexOf('.m4v') !== -1) {
            candidate = url.slice(0, url.indexOf('.m4v') + 4)
        } else if (url.indexOf('.webm') !== -1) {
            candidate = url.slice(0, url.indexOf('.webm') + 5)
        }

        let secondCheck = candidate.match(/(http:|https:|)\/\/(player.|www.)?(dropbox\.com)\/(s\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*\/)?(.*)/);
        if (secondCheck) {
            return 'https://dropbox.com/' + RegExp.$4 + RegExp.$5 + RegExp.$6 + '?raw=1'
        } else {
            throw Error("Not supported video resource.");
        }
    }
}
于 2020-04-16T12:30:59.000 回答
1

以防万一这是一个php版本

/*
* parseVideo
* @param (string) $url 
* mi-ca.ch 27.05.2016
* parse vimeo & youtube id
* format url for iframe embed 
* https://regex101.com/r/lA0fP4/1
*/

function parseVideo($url) {
  $re = "/(http:|https:|)\\/\\/(player.|www.)?(vimeo\\.com|youtu(be\\.com|\\.be|be\\.googleapis\\.com))\\/(video\\/|embed\\/|watch\\?v=|v\\/)?([A-Za-z0-9._%-]*)(\\&\\S+)?/"; 
preg_match($re, $url, $matches);

if(strrpos($matches[3],'youtu')>-1){
    $type='youtube';
    $src='https://www.youtube.com/embed/'.$matches[6];
}else if(strrpos($matches[3],'vimeo')>-1){
    $type="vimeo";
    $src='https://player.vimeo.com/video/'.$matches[6];
}else{
    return false;
}


return array(
         'type' =>  $type // return youtube or vimeo
        ,'id'   =>  $matches[6] // return the video id
        ,'src'  =>  $src // return the src for iframe embed
        );
} 
于 2016-04-27T11:40:30.170 回答
0

我以之前的答案为基础,但我需要更多的正则表达式。

也许它在 2011 年有效,但在 2019 年,语法发生了一些变化。所以这是一个刷新。

正则表达式将允许我们检测 url 是 Youtube 或 Vimeo 的天气。我添加了 Capture 组以轻松检索 videoID。

如果以不区分大小写的设置运行,请删除 (?i)。

(?:(?i)(?:https:|http:)?\/\/)?(?:(?i)(?:www\.youtube\.com\/(?:embed\/|watch\?v=)|youtu\.be\/|youtube\.googleapis\.com\/v\/)(?<YoutubeID>[a-z0-9-_]{11,12})|(?:vimeo\.com\/|player\.vimeo\.com\/video\/)(?<VimeoID>[0-9]+))

https://regex101.com/r/PVdjg0/2

于 2019-06-28T11:58:26.737 回答