Improving regex for parsing YouTube / Vimeo URLs

后端 未结 11 1506
半阙折子戏
半阙折子戏 2020-12-13 20:52

I\'ve made a function (in JavaScript) that takes an URL from either YouTube or Vimeo. It figures out the provider and ID for that particular video (demo: http://jsfiddle.net

相关标签:
11条回答
  • 2020-12-13 21:00

    Just in case here is a php version

    /*
    * 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
            );
    } 
    
    0 讨论(0)
  • 2020-12-13 21:02

    I based myself the previous answers but I needed more out the regex.

    Maybe it worked in 2011 but in 2019 the syntax has changed a bit. So this is a refresh.

    The regex will allow us to detect weather the url is Youtube or Vimeo. I've added Capture group to easily retrieve the videoID.

    If ran with Case insensitive setting please remove the (?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

    0 讨论(0)
  • 2020-12-13 21:03

    I am not sure about your question 3), but provided that your induction on the url forms is correct, the regexes can be combined into one as follows:

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

    You will get the match under different positions (1st and 2nd matches if vimeo, 3rd and 4th matches if youtube), so you just need to handle that.

    Or, if you are quite sure that vimeo's id only includes numbers, then you can do:

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

    and the provider and the id will apprear under 1st and 2nd match, respcetively.

    0 讨论(0)
  • 2020-12-13 21:03

    FWIW, I just used the following to validate and parse both YouTube and Vimeo URLs in an app. I'm sure you could add parentheses to parse out the specific things you're looking for...

    /^(?: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})[?]?.*$/
    

    ^^ This is just a combination of 2 separate expressions using | (or) to join them. Here are the original 2 expressions separately:

    /^(?: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})[?]?.*$/
    

    I'm no expert, but it seems to work according to Rubular. Hopefully this helps someone out in the future.

    0 讨论(0)
  • 2020-12-13 21:08

    Here's my attempt at the regex, which covers most updated cases:

    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
        };
    }
    
    0 讨论(0)
  • 2020-12-13 21:09

    about sawa's answer :

    a little update on the second regex :

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

    (escaping the dots prevents from matching url of type www_vimeo_com/… and $ added…)

    here is the same idea for matching the embed urls :

    /http:\/\/(?:www\.|player\.)?(vimeo|youtube)\.com\/(?:embed\/|video\/)?(.*?)(?:\z|$|\?)/
    
    0 讨论(0)
提交回复
热议问题