parse youtube video id using preg_match

72,649

Solution 1

This regex grabs the ID from all of the various URLs I could find... There may be more out there, but I couldn't find reference of them anywhere. If you come across one this doesn't match, please leave a comment with the URL, and I'll try and update the regex to match your URL.

if (preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/\s]{11})%i', $url, $match)) {
    $video_id = $match[1];
}

Here is a sample of the URLs this regex matches: (there can be more content after the given URL that will be ignored)

It also works on the youtube-nocookie.com URL with the same above options.

It will also pull the ID from the URL in an embed code (both iframe and object tags)

Solution 2

Better use parse_url and parse_str to parse the URL and query string:

$subject = "http://www.youtube.com/watch?v=z_AbfPXTKms&NR=1";
$url = parse_url($subject);
parse_str($url['query'], $query);
var_dump($query);

Solution 3

I had to deal with this for a PHP class i wrote a few weeks ago and ended up with a regex that matches any kind of strings: With or without URL scheme, with or without subdomain, youtube.com URL strings, youtu.be URL strings and dealing with all kind of parameter sorting. You can check it out at GitHub or simply copy and paste the code block below:

/**
 *  Check if input string is a valid YouTube URL
 *  and try to extract the YouTube Video ID from it.
 *  @author  Stephan Schmitz <[email protected]>
 *  @param   $url   string   The string that shall be checked.
 *  @return  mixed           Returns YouTube Video ID, or (boolean) false.
 */        
function parse_yturl($url) 
{
    $pattern = '#^(?:https?://)?(?:www\.)?(?:youtu\.be/|youtube\.com(?:/embed/|/v/|/watch\?v=|/watch\?.+&v=))([\w-]{11})(?:.+)?$#x';
    preg_match($pattern, $url, $matches);
    return (isset($matches[1])) ? $matches[1] : false;
}

To explain the regex, here's a spilt up version:

/**
 *  Check if input string is a valid YouTube URL
 *  and try to extract the YouTube Video ID from it.
 *  @author  Stephan Schmitz <[email protected]>
 *  @param   $url   string   The string that shall be checked.
 *  @return  mixed           Returns YouTube Video ID, or (boolean) false.
 */        
function parse_yturl($url) 
{
    $pattern = '#^(?:https?://)?';    # Optional URL scheme. Either http or https.
    $pattern .= '(?:www\.)?';         #  Optional www subdomain.
    $pattern .= '(?:';                #  Group host alternatives:
    $pattern .=   'youtu\.be/';       #    Either youtu.be,
    $pattern .=   '|youtube\.com';    #    or youtube.com
    $pattern .=   '(?:';              #    Group path alternatives:
    $pattern .=     '/embed/';        #      Either /embed/,
    $pattern .=     '|/v/';           #      or /v/,
    $pattern .=     '|/watch\?v=';    #      or /watch?v=,    
    $pattern .=     '|/watch\?.+&v='; #      or /watch?other_param&v=
    $pattern .=   ')';                #    End path alternatives.
    $pattern .= ')';                  #  End host alternatives.
    $pattern .= '([\w-]{11})';        # 11 characters (Length of Youtube video ids).
    $pattern .= '(?:.+)?$#x';         # Optional other ending URL parameters.
    preg_match($pattern, $url, $matches);
    return (isset($matches[1])) ? $matches[1] : false;
}

Solution 4

I perfected regex from the leader answer. It also grabs the ID from all of the various URLs, but more correctly.

if (preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[\w\-?&!#=,;]+/[\w\-?&!#=/,;]+/|(?:v|e(?:mbed)?)/|[\w\-?&!#=,;]*[?&]v=)|youtu\.be/)([\w-]{11})(?:[^\w-]|\Z)%i', $url, $match)) {
    $video_id = $match[1];
}

Also, it correctly handles the wrong IDs, which more than 11 characters.

http://www.youtube.com/watch?v=0zM3nApSvMgDw3qlxF

Solution 5

Use

 preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]/)[^&\n]+|(?<=v=)[^&\n]+#", $subject, $matches);
Share:
72,649
J.C
Author by

J.C

Web Developer based in UK

Updated on July 08, 2022

Comments

  • J.C
    J.C almost 2 years

    I am attempting to parse the video ID of a youtube URL using preg_match. I found a regular expression on this site that appears to work;

    (?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]/)[^&\n]+|(?<=v=)[^&\n]+
    

    As shown in this pic:

    alt text

    My PHP is as follows, but it doesn't work (gives Unknown modifier '[' error)...

    <?
     $subject = "http://www.youtube.com/watch?v=z_AbfPXTKms&NR=1";
    
     preg_match("(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]/)[^&\n]+|(?<=v=)[^&\n]+", $subject, $matches);
    
     print "<pre>";
     print_r($matches);
     print "</pre>";
    
    ?>
    

    Cheers

  • J.C
    J.C about 14 years
    This works but I just tested it with the URL youtube.com/v/z_AbfPXTKms&hl=en_GB&fs=1& and it fails, could you modify it to work with that format too?
  • Gumbo
    Gumbo about 14 years
    @Webbo: parse_url returns an array of the URL parts, so the URL path is also in there. You need to do some further case differentiation to what type the URL is.
  • J.C
    J.C about 14 years
    I would rather use a regex to do it all in one
  • Anton
    Anton about 14 years
    it works ! i had tried? gimme any example that does not fit on this criteria?
  • Anton
    Anton about 14 years
    other related post http://stackoverflow.com/questions/2164040/grab-the-youtube-‌​video-id-with-jquery‌​-match`
  • J.C
    J.C about 14 years
    I am accepting this answer as it does answer my original question. I am now working on modifying it to work with the URL youtube.com/v/z_AbfPXTKms&hl=en_GB&fs=1&
  • Jason Yost
    Jason Yost over 12 years
    I am using the expression provided above and I always get the ending /iframe> in the video ID.
  • Benjam
    Benjam over 12 years
    Can you give a link to a pastebin example of what exactly you are doing? Or create a question here on SO and link to it here?
  • Benjam
    Benjam over 12 years
    Again... do you have a code sample? Are you using it correctly? I just tested it with your URL, and it returned an array and in $match[1] was '9ofSV-ATEB0', which IS the id.
  • Juan Gonzales
    Juan Gonzales about 12 years
    @Benjam do you have a preg_match for vimeo that is like this one! This is a great regX +1. Thanks!
  • Flexo
    Flexo about 12 years
    Please don't post your answer multiple times. Instead flag as duplicates or add a comment saying that there's an answer on another question if they're not exact duplicates but it's still relevant.
  • eyecatchUp
    eyecatchUp about 12 years
    @awoodland: No prob and thanks for pointing me to the possibilty to flag questions as duplicates.
  • Lode
    Lode over 11 years
    I've got better results for /?v= and iframe/object variants when moving the username/... check ([^/]+/.+/) to the back: %(?:youtube(?:-nocookie)?\.com/(?:(?:v|e(?:mbed)?)/|.*[?&]v=‌​|[^/]+/.+/)|youtu\.b‌​e/)([^"&?/ ]{11})%i. For other variants it remains the same.
  • Modder
    Modder over 9 years
    Maybe instead [^"&?/ ]{11} make this [a-z0-9-_]{11}?
  • Benjam
    Benjam over 9 years
    @Modder, because there are more characters than [a-z0-9-_] (which should be [a-z0-9_-], btw) allowed in YouTube IDs. And because I don't have a definitive list of what those characters are, I instead looked for anything that I knew it couldn't be, namely [^"&?/ ]. I realize that even the blacklisted character list is incomplete, but, supplied with a valid YouTube URL, it works.
  • Modder
    Modder over 9 years
    Not need to escape the slash if at the begin and at the end of regex you use a character other than slash, like #
  • Benjam
    Benjam almost 9 years
    @NimitzE. - Should work out of the box. It's only looking for the youtube.com portion, and doesn't care about www. or m..
  • optimus prime
    optimus prime over 8 years
    @Benjam, I am new to these, can you please explain me the regular express? what does %i and ? and others for? Please
  • Benjam
    Benjam over 8 years
    Regular Expressions are far too complex for a lesson in a comment field. I recommend reading regular-expressions.info