改进正则表达式以解析YouTube/Vimeo URL

Dan*_*iel 16 javascript regex youtube vimeo

我已经创建了一个函数(在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
    }
}
Run Code Online (Sandbox Code Playgroud)

它有效,但作为正则表达式新手,我正在寻找改进它的方法.我正在处理的输入,通常如下所示:

http://vimeo.com/(id)
http://youtube.com/watch?v=(id)&blahblahblah.....
Run Code Online (Sandbox Code Playgroud)

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

2)现有的比赛能更简洁吗?它们是不必要的复杂吗?或者可能不够?

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

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

Yan*_*Tay 22

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

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(/(http:\/\/|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
    };
}
Run Code Online (Sandbox Code Playgroud)


Jas*_*ing 11

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

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];
}
Run Code Online (Sandbox Code Playgroud)

有时简单的代码对你的开发人员来说更好.

https://jsfiddle.net/1dzb5ag1/

// protocol and www neutral
function getVideoId(url, prefixes) {
  var cleaned = url.replace(/^(https?:)?\/\/(www\.)?/, '');
  for(var i = 0; i < prefixes.length; i++) {
    if (cleaned.indexOf(prefixes[i]) === 0)
      return cleaned.substr(prefixes[i].length)
  }
  return undefined;
}

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

function getVimeoId(url) {
  return getVideoId(url, [
    'vimeo.com/',
    'player.vimeo.com/'
  ]);
}
Run Code Online (Sandbox Code Playgroud)

您更喜欢哪个?


saw*_*awa 10

我不确定您的问题3),但如果您对网址表单的归纳是正确的,那么正则表达式可以合并为一个如下:

/http:\/\/(?:www.)?(?:(vimeo).com\/(.*)|(youtube).com\/watch\?v=(.*?)&)/
Run Code Online (Sandbox Code Playgroud)

您将获得不同位置的比赛(如果是vimeo,则第一和第二场比赛,如果是youtube,则为第3和第4场比赛),因此您只需要处理.

或者,如果您确定vimeo的id仅包含数字,那么您可以:

/http:\/\/(?:www.)?(vimeo|youtube).com\/(?:watch\?v=)?(.*?)(?:\z|&)/
Run Code Online (Sandbox Code Playgroud)

并且提供者和身份证将在第一和第二场比赛中得到满足.


Min*_*ang 7

这是我的正则表达式

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


Rom*_*ain 6

关于sawa的回答:

关于第二个正则表达式的一点更新:

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

(转义点可防止匹配www_vimeo_com/...类型的URL和$ added ...)

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

/http:\/\/(?:www\.|player\.)?(vimeo|youtube)\.com\/(?:embed\/|video\/)?(.*?)(?:\z|$|\?)/
Run Code Online (Sandbox Code Playgroud)


flu*_*man 5

对于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/*/*
Run Code Online (Sandbox Code Playgroud)

而是使用其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
  }
});
Run Code Online (Sandbox Code Playgroud)