46

I know there is plenty of question answered over here https://stackoverflow.com/questions/tagged/youtube+regex, but not able find a question similar to me.

Any body has the JavaScript Regular expression for validating the YouTube VIDEO URL's line below listed. Just want to know where such a URL can be possible

http://www.youtube.com/watch?v=bQVoAWSP7k4
http://www.youtube.com/watch?v=bQVoAWSP7k4&feature=popular
http://www.youtube.com/watch?v=McNqjYiFmyQ&feature=related&bhablah
http://youtube.com/watch?v=bQVoAWSP7k4

-- update 1-- -- update 2--

This one worked almost fine, but failed for the URL http://youtube.com/watch?v=bQVoAWSP7k4

var matches = $('#videoUrl').val().match(/http:\/\/(?:www\.)?youtube.*watch\?v=([a-zA-Z0-9\-_]+)/);
if (matches) {
    alert('valid');
} else {
    alert('Invalid');
}
Community
  • 1
  • 1
Mithun Sreedharan
  • 49,883
  • 70
  • 181
  • 236
  • 1
    That regex you have there is very troublesome. Particularly the `.*` portion which matches anything. This means that it would also match the following url: `http://hackersrus.com/youtube-watch?v=a` – Senseful Jun 03 '10 at 09:51
  • oops! changed to var matches = $('#videoUrl').val().match(/http:\/\/(?:www\.)?youtube.*watch\?v=([a-zA-Z0-9\-_]+)/); if (matches) { alert('valid'); } else { alert('Invalid'); } – Mithun Sreedharan Jun 03 '10 at 10:04
  • Still false, see my answer for a fully correct way. – eyecatchUp May 09 '12 at 10:27

9 Answers9

199

ULTIMATE YOUTUBE REGEX

Cherry picking

Because the explanation is getting longer and longer, I place the final result at the top. Feel free to copy+paste, and go on your way. For a detailed explanation, read _"the full story"_ below.
/**
 * JavaScript function to match (and return) the video Id 
 * of any valid Youtube Url, given as input string.
 * @author: Stephan Schmitz <eyecatchup@gmail.com>
 * @url: https://stackoverflow.com/a/10315969/624466
 */
function ytVidId(url) {
  var p = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
  return (url.match(p)) ? RegExp.$1 : false;
}

The full story

Amarghosh's regex looks good, at first sight. But it:

  1. doesn't match video id's that include dashes (-),
  2. doesn't validate the id length (v=aa and v=aaaaaaaaaaaaaaaaaa return to be valid),
  3. and doesn't match secured URLs at all (https://youtube.com/watch?valid_params)

To match https, the dash character, and to validate the id length, this was my initial suggestion of a modified version of Amarghosh's regex:

^https?:\/\/(?:www\.)?youtube\.com\/watch\?(?=.*v=((\w|-){11}))(?:\S+)?$

UPDATE 1: URLs versus Strings

After I posted the above pattern, I was asked: "What if the URL is like this;
youtube.com/watch?gl=US&hl=en-US&v=bQVoAWSP7k4"
?

First of, please note that this not a URL at all. RFC compliant URLs must start with the scheme! ;)

Anyway, to match any kind of string that indicates to refer to a YouTube video, I updated my answer to exclude the URL scheme being required. So my second suggestion was as follows:

^(?:https?:\/\/)?(?:www\.)?youtube\.com\/watch\?(?=.*v=((\w|-){11}))(?:\S+)?$

UPDATE 2: The ultimate regex

Then I was asked to add support for a "special case"; the youtu.be short urls. Initially I did not add these, since it wasn't specifically part of the question. However I updated my answer now with all possible "special cases". This means that not only have I added support for youtu.be links, but also the request paths "/v" and "/embed".

So, may I introduce: My final and ultimate Youtube regex:

^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$

What strings are matched?

Now this pattern will work for any strings, formatted as follows:

Without scheme and subdomain (Domain: youtu.be, Path: /)

youtu.be/<video:id>   

Without scheme, with subdomain (Domain: youtu.be, Path: /)

www.youtu.be/<video:id>     

With HTTP scheme, without subdomain (Domain: youtu.be, Path: /)

http://youtu.be/<video:id>   

With HTTP scheme and subdomain (Domain: youtu.be, Path: /)

http://www.youtu.be/<video:id>   

With HTTPS scheme, without subdomain (Domain: youtu.be, Path: /)

https://youtu.be/<video:id>     

With HTTPS scheme and subdomain (Domain: youtu.be, Path: /)

https://www.youtu.be/<video:id>   

Without scheme and subdomain (Domain: youtube.com, Path: /embed)

youtube.com/embed/<video:id>   
youtube.com/embed/<video:id>&other_params 

Without scheme, with subdomain (Domain: youtube.com, Path: /embed)

www.youtube.com/embed/<video:id>   
www.youtube.com/embed/<video:id>&other_params   

With HTTP scheme, without subdomain (Domain: youtube.com, Path: /embed)

http://youtube.com/embed/<video:id>   
http://youtube.com/embed/<video:id>&other_params  

With HTTP scheme and subdomain (Domain: youtube.com, Path: /embed)

http://www.youtube.com/embed/<video:id>   
http://www.youtube.com/embed/<video:id>&other_params  

With HTTPS scheme, without subdomain (Domain: youtube.com, Path: /embed)

https://youtube.com/embed/<video:id>   
https://youtube.com/embed/<video:id>&other_params    

With HTTPS scheme and subdomain (Domain: youtube.com, Path: /embed)

https://www.youtube.com/embed/<video:id>   
https://www.youtube.com/embed/<video:id>&other_params

Without scheme and subdomain (Domain: youtube.com, Path: /v)

youtube.com/v/<video:id>   
youtube.com/v/<video:id>&other_params 

Without scheme, with subdomain (Domain: youtube.com, Path: /v)

www.youtube.com/v/<video:id>   
www.youtube.com/v/<video:id>&other_params   

With HTTP scheme, without subdomain (Domain: youtube.com, Path: /v)

http://youtube.com/v/<video:id>   
http://youtube.com/v/<video:id>&other_params  

With HTTP scheme and subdomain (Domain: youtube.com, Path: /v)

http://www.youtube.com/v/<video:id>   
http://www.youtube.com/v/<video:id>&other_params  

With HTTPS scheme, without subdomain (Domain: youtube.com, Path: /v)

https://youtube.com/v/<video:id>   
https://youtube.com/v/<video:id>&other_params    

With HTTPS scheme and subdomain (Domain: youtube.com, Path: /v)

https://www.youtube.com/v/<video:id>   
https://www.youtube.com/v/<video:id>&other_params   

Without scheme and subdomain (Domain: youtube.com, Path: /watch)

youtube.com/watch?v=<video:id>   
youtube.com/watch?v=<video:id>&other_params   
youtube.com/watch?other_params&v=<video:id> 
youtube.com/watch?other_params&v=<video:id>&more_params  

Without scheme, with subdomain (Domain: youtube.com, Path: /watch)

www.youtube.com/watch?v=<video:id>   
www.youtube.com/watch?v=<video:id>&other_params   
www.youtube.com/watch?other_params&v=<video:id>  
www.youtube.com/watch?other_params&v=<video:id>&more_params   

With HTTP scheme, without subdomain (Domain: youtube.com, Path: /watch)

http://youtube.com/watch?v=<video:id>   
http://youtube.com/watch?v=<video:id>&other_params   
http://youtube.com/watch?other_params&v=<video:id>   
http://youtube.com/watch?other_params&v=<video:id>&more_params  

With HTTP scheme and subdomain (Domain: youtube.com, Path: /watch)

http://www.youtube.com/watch?v=<video:id>   
http://www.youtube.com/watch?v=<video:id>&other_params   
http://www.youtube.com/watch?other_params&v=<video:id>   
http://www.youtube.com/watch?other_params&v=<video:id>&more_params  

With HTTPS scheme, without subdomain (Domain: youtube.com, Path: /watch)

https://youtube.com/watch?v=<video:id>   
https://youtube.com/watch?v=<video:id>&other_params   
https://youtube.com/watch?other_params&v=<video:id>   
https://youtube.com/watch?other_params&v=<video:id>&more_params     

With HTTPS scheme and subdomain (Domain: youtube.com, Path: /watch)

https://www.youtube.com/watch?v=<video:id>   
https://www.youtube.com/watch?v=<video:id>&other_params   
https://www.youtube.com/watch?other_params&v=<video:id>
https://www.youtube.com/watch?other_params&v=<video:id>&more_params  

FUNCTIONAL USAGE

The most easy way to use the pattern, is to wrap it into a function such as this one:

/**
 * JavaScript function to match (and return) the video Id
 * of any valid Youtube Url, given as input string.
 * @author: Stephan Schmitz <eyecatchup@gmail.com>
 * @url: https://stackoverflow.com/a/10315969/624466
 */
function ytVidId(url) {
  var p = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
  return (url.match(p)) ? RegExp.$1 : false;
}

// for example snippet only!
document.body.addEventListener('click', function(e) {
    if (e.target.className == 'yt-url' && 'undefined' !== e.target.value) {
        var ytId = ytVidId(e.target.value);
        alert(e.target.value + "\r\nResult: " + (!ytId ? 'false' : ytId));
    }
}, false);
<!-- Click the buttons to probe URLs -->
<input type="button" value="https://www.youtube.com/watch?v=p-e2G_VcTms&feature=g-logo&context=G29aead6FOAAAAAAABAA" class="yt-url">
<input type="button" value="https://www.youtube.com/latest" class="yt-url">

If the type of the function's result value must be a boolean value, just replace RegExp.$1 by true. That's it.

One final note on the video Id length: One asked if the ids have a fixed length of 11 chars? and if it might change in the future?

The best answer to that question is probably also the only "official" statement that I've found here and which says: "I don't see anywhere in the documentation where we officially commit to a standard length of 11 characters for YouTube video ids. It's one of those things where we have a current implementation, and it may stay that way indefinitely. But we're not offering any official commitment to that, so proceed at your own risk."

Community
  • 1
  • 1
eyecatchUp
  • 10,032
  • 4
  • 55
  • 65
  • 2
    youtube.com part in your regexp can match anything like youtubeXcom, you should escape that period – Yasin Ergul Apr 29 '12 at 07:53
  • What if the URL is like this; http://www.youtube.com/watch?gl=US&hl=en-US&v=bQVoAWSP7k4 – FizzBuzz May 07 '12 at 03:23
  • @FizzBuzz Well, that is not a valid URL at all (even though (most) web browsers will accept this input)! [RFC compliant URLs](http://tools.ietf.org/html/rfc3986#page-16) must provide _a means of locating the resource by describing its primary access mechanism_ which refers to the valid URI syntax that always starts with the access scheme. However, you could make the scheme optional in the regex like this: `var pattern = /^(?:https?:\/\/)?(?:www\.)?youtube\.com\/watch\?(?=.*v=((\w|-){11}))(?:\S+)?$/;` Does that answer your question? – eyecatchUp May 09 '12 at 09:31
  • What about http://youtu.be/_d6KuiuteIA which you get if you select the embed option? – Dan Diplo May 22 '12 at 15:52
  • @DanDiplo: I focused on "watch"-URLs, since the question did. But you can easily expand the pattern to group path alternatives, too. Take a look at my answer here: http://stackoverflow.com/a/10524505/624466. The pattern is used with PHP, but you can easily adapt it for use with JS. – eyecatchUp May 25 '12 at 10:46
  • there is another special case to add: http://youtu.be/8mwKq7_JlS8 I'm talking about the links provided by share button provided by youtube webapp which use youtu.be – dole doug Jan 09 '13 at 15:43
  • @doledoug: The question about _youtu.be_ URL-like strings was already answered (see question from Dan Diplo upthread). However, I updated the answer now. Is that what you're looking for? ;-) Now there shouldn't be any more _"special cases"_ to add. This should be the ultimate regex now. – eyecatchUp Jan 09 '13 at 21:00
  • I've made it even more ultimate by making it work correctly and also support the `-nocookie` domain: `/^(?:https?:\/\/)?(?:www\.)?(?:(?:youtu\.be\/|youtube(?:\-nocookie)?\.com\/)(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|\-){11})(?:\S+)?$/` – Nijikokun Jun 13 '13 at 07:47
  • It worked correctly before. :P But thanks for the update anyway! Will add it to the answer later. – eyecatchUp Jun 13 '13 at 08:34
  • Thanks a lot, great solution. Also a special thanks for being so specific! – Oleg Belousov Dec 19 '13 at 16:09
  • Awesome job, you won my internets. This should be "sticky" lol – Krynble Apr 08 '14 at 19:57
  • check this buddy http://stackoverflow.com/questions/18362164/what-does-regexp-1-do/18362308#18362308 – Jitendra Pancholi Feb 26 '15 at 10:02
  • @JitendraPancholi Reconsidering when to replace it. Thanks. – eyecatchUp Apr 15 '15 at 22:14
  • 1
    It gives following warning "nested repeat operator '+' and '?' was replaced with '*' in regular expression" – lightsaber Apr 28 '15 at 05:39
  • @eyecatchUp badly need a youtube "playlist" ultimate youtube regex :) work your magic :D or maybe I can do this :D – Ankan-Zerob Feb 13 '16 at 12:11
  • Not really "ultimate", the provided expression will fail with any Youtube url sent via channel subscription, like this: "**http://www.youtube.com/attribution_link?a=Od7TH6HFkco&u=/watch?v%3DHzmn4-vtl5M%26feature%3Dem-uploademail**", also, I'm not sure if the current expression is validating other fields such as "**&feature=em-uploademail**", any update to this, please?. thanks in advance! – ElektroStudios Mar 21 '16 at 14:01
  • **RegExp.$1-$9** [is Deprecated](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features#RegExp_Properties) – befzz Mar 31 '16 at 17:08
  • The last part: `(?:\S+)?`. Why to use two repeat operators (+, ?)? [gives me a warning in ruby]. Isn't `(?:\S*)` more convenient? – optimista Aug 30 '17 at 23:09
  • This seems to validate for video IDs longer than 11 characters too. Any ideas how to fix? Also, any replacement for RegExp.$1? Seems to be deprecated. – yenren Oct 06 '20 at 08:22
  • Can anyone get this to work with HTML input pattern? ie ** – SuperUberDuper Dec 24 '20 at 17:38
  • @ElektroStudios this really should be a gist now or even repo – SuperUberDuper Dec 24 '20 at 17:39
  • @SuperUberDuper Not sure, what exactly fails. But for me the regex works fine as an input pattern as well. See https://codepen.io/eyecatchup/pen/mdrxzmj – eyecatchUp Jan 04 '21 at 02:23
  • How do you make it still work if the string contains a youtube link with some text. For example, 'check this video: https://www.youtube.com/watch?v=LZk4vbLG0jU ' – Joshua Bitton Feb 24 '21 at 05:40
  • @JoshuaBitton Just remove the leading `^` and trailing `$` from the regex, like so: `/(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?/`. See: https://codepen.io/eyecatchup/pen/jOVaovX – eyecatchUp Feb 24 '21 at 09:29
  • how would you be able to return the link and console.log the message in the string, so it would be a string containing the youtube link and the message – Joshua Bitton Feb 25 '21 at 00:17
  • Can we get this to work with shorts? Like with this link [https://www.youtube.com/shorts/jhX_oSfYGiI](https://www.youtube.com/shorts/jhX_oSfYGiI) – soloko Aug 12 '22 at 22:14
20
^http:\/\/(?:www\.)?youtube.com\/watch\?v=\w+(&\S*)?$

//if v can be anywhere in the query list

^http:\/\/(?:www\.)?youtube.com\/watch\?(?=.*v=\w+)(?:\S+)?$
Amarghosh
  • 58,710
  • 11
  • 92
  • 121
4

You can not match the id-part with \w+, as it does not include the dash character (-). [a-zA-Z0-9_-]+ would be something more correct.

safdsas
  • 105
  • 3
  • You can not validate the id length with +, {11} would be something more correct. ;) – eyecatchUp Apr 25 '12 at 12:50
  • Forgot to mention that (\w|-) is shorter than [a-zA-Z0-9_-]. :p ;) – eyecatchUp Apr 25 '12 at 13:24
  • is ids fixed to 11 chars? it might be change in the future? – Yasin Ergul Apr 29 '12 at 07:39
  • 1
    The best answer to that question is probably also the only "official" statement i've found here http://groups.google.com/group/youtube-api-gdata/browse_thread/thread/a00ced4377f5b5c3/e3602552c32f376f and which says "I don't see anywhere in the documentation where we officially commit to a standard length of 11 characters for YouTube video ids. It's one of those things where we have a current implementation, and it may stay that way indefinitely. But we're not offering any official commitment to that, so proceed at your own risk." – eyecatchUp May 01 '12 at 14:30
2

@eyecatchup ubove has an excelent regex, but with the help of regexper.com i saw that his regex will pass any youtube url where the ?v parameter had a value of any word or - sign repeated 11 times. But youtube specificly restricts the video id to 11 characters so a fix for his regex would be

/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((.|-){11})(?:\S+)?$/

compare the vizualization of his regex

http://www.regexper.com/#/%5E%28?:https?:%5C/%5C/%29?%28?:www%5C.%29?%28?:youtu%5C.be%5C/%7Cyoutube%5C.com%5C/%28?:embed%5C/%7Cv%5C/%7Cwatch%5C?v=%7Cwatch%5C?.%2b&v=%29%29%28%28%5Cw%7C-%29%7B11%7D%29%28?:%5CS%2b%29?$/

and my fix

http://www.regexper.com/#%2F%5E(%3F%3Ahttps%3F%3A%5C%2F%5C%2F)%3F(%3F%3Awww%5C.)%3F(%3F%3Ayoutu%5C.be%5C%2F%7Cyoutube%5C.com%5C%2F(%3F%3Aembed%5C%2F%7Cv%5C%2F%7Cwatch%5C%3Fv%3D%7Cwatch%5C%3F.%2B%26v%3D))((%5Ba-zA-Z0-9%5D%7C-)%7B11%7D)(%3F%3A%5CS%2B)%3F%24%2F

as an edit to the 11 character limit changing in future then the current regex would mean that any word or - would have to be repeated exactly 11 times, to that my fix is

/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11,})(?:\S+)?$/
1

Improvement for @eyecatchUp's great regex:

  1. Add support for m.youtube.com domain
  2. Add support for youtube-nocookie.com domain by @Nijikokun
^(?:https?:\/\/)?(?:(?:www|m)\.)?(?:youtu\.be\/|youtube(?:-nocookie)?\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$

Regexper:

http://regexper.com/#%5E(%3F%3Ahttps%3F%3A%5C%2F%5C%2F)%3F(%3F%3A(%3F%3Awww%7Cm)%5C.)%3F(%3F%3Ayoutu%5C.be%5C%2F%7Cyoutube(%3F%3A-nocookie)%3F%5C.com%5C%2F(%3F%3Aembed%5C%2F%7Cv%5C%2F%7Cwatch%5C%3Fv%3D%7Cwatch%5C%3F.%2B%26v%3D))((%5Cw%7C-)%7B11%7D)(%3F%3A%5CS%2B)%3F%24
Mrskman
  • 332
  • 2
  • 10
1
 /* test youtube */
 var src = "https://www.youtube.com/watch?v=HCPLKrRguDM";
  regExTestYT(src);
   function regExTestYT(str){
   var exp = new RegExp(/(youtu\.be|youtube\.com)/);
   return exp.test(str); 
  }
Someshver Thakur
  • 162
  • 1
  • 11
1

Here it is with Youtube shorts added:

/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|(?:shorts\/)|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/

soloko
  • 222
  • 2
  • 14
-3
function get_youtube_video_id_from_url(url){
    var code = url.match(/v=([^&#]{5,})/)
    return (typeof code[1] == 'string') ? code[1] : false;
}
HiTech
  • 295
  • 2
  • 7
  • Wrong at all. This matches even `var url = 'v=abcde';`. Furthermore, if no match is found, you produce a `TypeError: Cannot read property '1' of null`. – eyecatchUp May 07 '14 at 05:38
-5
function validYT(url) {
  var p = /^(?:https?:\/\/)?(?:www\.)?youtube\.com\/watch\?(?=.*v=((\w|-){11}))(?:\S+)?$/;
  return (url.match(p)) ? RegExp.$1 : false;
}
Taryn
  • 242,637
  • 56
  • 362
  • 405
user1948368
  • 213
  • 3
  • 3