Regex to extract domain and video id from youtube/vimeo url

Ryan Ellis picture Ryan Ellis · Mar 4, 2012 · Viewed 9.8k times · Source

I am copying a function that will take a youtube/vimeo url and return what site the video came from (vimeo/yt) as well as the video id.

Here's what I have so far: http://jsfiddle.net/csjwf/181/

<strong>Result:</strong>
<div id="result"></div>
function parseVideoURL(url) {

    url.match(/^http:\/\/(?:.*?)\.?(youtube|vimeo)\.com\/(watch\?[^#]*v=(\w+)|(\d+)).+$/);
    return {
        provider : RegExp.$1,
        id : RegExp.$1 == 'vimeo' ? RegExp.$2 : RegExp.$3
    }
}

var result = document.getElementById("result");
var video = parseVideoURL("http://www.youtube.com/watch?v=PQLnmdOthmA&feature=feedrec_grec_index");
result.innerHTML = "Provider: " + video.provider + "<br>ID: " + video.id;

var video = parseVideoURL("http://vimeo.com/22080133");

result.innerHTML += "<br>--<br>Provider: " + video.provider + "<br>ID: " + video.id;

Output:

Result:
Provider: youtube
ID: PQLnmdOthmA
--
Provider: vimeo
ID: 2208013

However, notice how for vimeo vids, if the url ends in the ID, the last number is always cut off. If you add a slash to the end of the vimeo url the id is pulled fully.

Answer

jfriend00 picture jfriend00 · Mar 4, 2012

The .+$ at the end is requiring at least one character after the last digit that is captured as a string of digits. That will chop one digit off what is captured. Is there a reason you have that there?

You can change the last + to a * like this:

/^http:\/\/(?:.*?)\.?(youtube|vimeo)\.com\/(watch\?[^#]*v=(\w+)|(\d+)).*$/

or even better, get rid of the end part entirely since it doesn't look like it's needed:

/^http:\/\/(?:.*?)\.?(youtube|vimeo)\.com\/(watch\?[^#]*v=(\w+)|(\d+))/

Here's a bit safer way to write your function that allows for any order of the query parameters in the youtube URL and doesn't put stuff into the regex that doesn't need to be there. The code is longer, but it's much more robust and would be much easier to add more providers:

function parseVideoURL(url) {

    function getParm(url, base) {
        var re = new RegExp("(\\?|&)" + base + "\\=([^&]*)(&|$)");
        var matches = url.match(re);
        if (matches) {
            return(matches[2]);
        } else {
            return("");
        }
    }

    var retVal = {};
    var matches;

    if (url.indexOf("youtube.com/watch") != -1) {
        retVal.provider = "youtube";
        retVal.id = getParm(url, "v");
    } else if (matches = url.match(/vimeo.com\/(\d+)/)) {
        retVal.provider = "vimeo";
        retVal.id = matches[1];
    }
    return(retVal);
}

Working version here: http://jsfiddle.net/jfriend00/N2hPj/