parse youtube video id using preg_match
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)
- http://youtu.be/dQw4w9WgXcQ ...
- http://www.youtube.com/embed/dQw4w9WgXcQ ...
- http://www.youtube.com/watch?v=dQw4w9WgXcQ ...
- http://www.youtube.com/?v=dQw4w9WgXcQ ...
- http://www.youtube.com/v/dQw4w9WgXcQ ...
- http://www.youtube.com/e/dQw4w9WgXcQ ...
- http://www.youtube.com/user/username#p/u/11/dQw4w9WgXcQ ...
- http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/0/dQw4w9WgXcQ ...
- http://www.youtube.com/watch?feature=player_embedded&v=dQw4w9WgXcQ ...
- http://www.youtube.com/?feature=player_embedded&v=dQw4w9WgXcQ ...
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);
Comments
-
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:
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 about 14 yearsThis 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 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 about 14 yearsI would rather use a regex to do it all in one
-
Anton about 14 yearsit works ! i had tried? gimme any example that does not fit on this criteria?
-
Anton about 14 yearsother related post
http://stackoverflow.com/questions/2164040/grab-the-youtube-video-
id-with-jquery-match` -
J.C about 14 yearsI 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 over 12 yearsI am using the expression provided above and I always get the ending /iframe> in the video ID.
-
Benjam over 12 yearsCan 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 over 12 yearsAgain... 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 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 about 12 yearsPlease 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 about 12 years@awoodland: No prob and thanks for pointing me to the possibilty to flag questions as duplicates.
-
Lode over 11 yearsI'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\.be/)([^"&?/ ]{11})%i
. For other variants it remains the same. -
Modder over 9 yearsMaybe instead
[^"&?/ ]{11}
make this[a-z0-9-_]{11}
? -
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 over 9 yearsNot need to escape the slash if at the begin and at the end of regex you use a character other than slash, like
#
-
Benjam almost 9 years@NimitzE. - Should work out of the box. It's only looking for the
youtube.com
portion, and doesn't care aboutwww.
orm.
. -
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 over 8 yearsRegular Expressions are far too complex for a lesson in a comment field. I recommend reading regular-expressions.info