使用正则表达式验证 jQuery Youtube URL

IT技术 javascript jquery regex url youtube
2021-01-27 06:28:43

我知道这里有很多问题的答案https://stackoverflow.com/questions/tagged/youtube+regex,但找不到与我类似的问题。

任何正文都有用于验证下面列出的 YouTube 视频 URL 行的 JavaScript 正则表达式。只是想知道哪里可能有这样的 URL

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

-- 更新 1-- -- 更新 2--

这个几乎可以正常工作,但是对于 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');
}
6个回答

终极 YouTube 正则表达式

采摘樱桃

因为解释的时间越来越长,我把​​最后的结果放在最上面。随意复制+粘贴,然后继续。有关详细说明,请阅读下面的_“完整故事”_。
/**
 * 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;
}

完整的故事

乍一看,Amarghosh 的正则表达式看起来不错。但它:

  1. 与包含破折号 (-) 的视频 ID 不匹配,
  2. 不验证 id 长度(v=aav=aaaaaaaaaaaaaaaaaa返回有效),
  3. 并且根本不匹配受保护的 URL (http s ://youtube.com/watch?valid_params)

为了匹配 https、破折号字符并验证 id 长度,这是我对 Amarghosh 正则表达式的修改版本的初步建议:

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

更新 1:URL 与字符串

在我贴出上述模式后,有人问我:“如果URL是这样的
youtube.com/watch?gl=US&hl=en-US&v=bQVoAWSP7k4
怎么办

首先,请注意这根本不是URL符合 RFC 的 URL必须以方案开头!;)

无论如何,为了匹配任何类型的表示引用 YouTube 视频字符串,我更新了我的答案以排除所需的 URL 方案。所以我的第二个建议如下:

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

更新 2:终极正则表达式

然后我被要求添加对“特殊情况”的支持;youtu.be短网址。最初我没有添加这些,因为它不是问题的具体部分。但是,我现在用所有可能的“特殊情况”更新了我的答案这意味着我不仅添加了对 youtu.be 链接的支持,还添加了请求路径“/v”和“/embed”。

那么,我可以介绍一下:我的最终和最终的 Youtube 正则表达式:

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

匹配哪些字符串?

现在这个模式适用于任何字符串,格式如下:

没有方案和子域(域:youtu.be,路径:/)

youtu.be/<video:id>   

没有方案,有子域(域:youtu.be,路径:/)

www.youtu.be/<video:id>     

带HTTP方案,不带子域(域:youtu.be,路径:/)

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

使用 HTTP 方案和子域(域:youtu.be,路径:/)

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

使用 HTTPS 方案,无子域(域:youtu.be,路径:/)

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

使用 HTTPS 方案和子域(域:youtu.be,路径:/)

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

没有方案和子域(域:youtube.com,路径:/embed)

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

没有方案,有子域(域:youtube.com,路径:/embed)

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

使用 HTTP 方案,没有子域(域:youtube.com,路径:/embed)

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

使用 HTTP 方案和子域(域:youtube.com,路径:/embed)

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

使用 HTTPS 方案,没有子域(域:youtube.com,路径:/embed)

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

使用 HTTPS 方案和子域(域:youtube.com,路径:/embed)

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

没有方案和子域(域:youtube.com,路径:/v)

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

没有方案,有子域(域:youtube.com,路径:/v)

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

使用 HTTP 方案,没有子域(域:youtube.com,路径:/v)

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

使用 HTTP 方案和子域(域:youtube.com,路径:/v)

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

使用 HTTPS 方案,没有子域(域:youtube.com,路径:/v)

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

使用 HTTPS 方案和子域(域:youtube.com,路径:/v)

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

没有方案和子域(域:youtube.com,路径:/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  

没有方案,有子域(域:youtube.com,路径:/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   

使用 HTTP 方案,没有子域(域:youtube.com,路径:/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  

使用 HTTP 方案和子域(域:youtube.com,路径:/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  

使用 HTTPS 方案,没有子域(域:youtube.com,路径:/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     

使用 HTTPS 方案和子域(域:youtube.com,路径:/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  

功能用途

使用该模式的最简单方法是将其包装成一个函数,例如:

/**
 * 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">

如果函数结果值的类型必须是布尔值,只需替换RegExp.$1true而已。

关于视频 ID 长度的最后一个说明:有人问 id 是否具有 11 个字符的固定长度?如果将来可能会改变?

这个问题的最佳答案可能也是我在这里找到的唯一“官方”声明,它说:“我在文档中没有看到我们正式Promise YouTube 视频 ID 的标准长度为 11 个字符的任何地方. 这是我们当前实施的其中一件事,它可能会无限期地保持这种状态。但我们不会对此提供任何官方Promise,因此请自行承担风险。”

如果 URL 是这样的怎么办?youtube.com/watch?gl=US&hl=en-US&v=bQVoAWSP7k4
2021-03-20 06:28:43
它给出以下警告“嵌套重复运算符'+'和'?' 在正则表达式中被'*'替换"
2021-03-26 06:28:43
如果选择嵌入选项,你得到的youtu.be/_d6KuiuteIA怎么样
2021-03-31 06:28:43
@FizzBu​​zz 好吧,这根本不是有效的 URL(即使(大多数)Web 浏览器会接受此输入)!符合 RFC 的 URL必须通过描述其主要访问机制提供一种定位资源的方法,该机制指的是始终以访问方案开头的有效 URI 语法。但是,您可以像这样在正则表达式中选择该方案:这var pattern = /^(?:https?:\/\/)?(?:www\.)?youtube\.com\/watch\?(?=.*v=((\w|-){11}))(?:\S+)?$/;是否回答了您的问题?
2021-04-04 06:28:43
正则表达式中的 youtube.com 部分可以匹配 youtubeXcom 之类的任何内容,您应该避开那个时期
2021-04-09 06:28:43
^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+)?$
2021-03-20 06:28:43
@Amarghosh ,您能否礼貌地告诉 2 个网址中的哪些网址是正确的?做一些解释是不是很困难?
2021-03-20 06:28:43
有关改进版本,请参阅我的答案(stackoverflow.com/a/10315969/624466)。
2021-03-27 06:28:43
正则表达式中的 youtube.com 部分可以匹配 youtubeXcom 之类的任何内容,您应该避开那个时期
2021-03-29 06:28:43

您不能将 id-part 与 \w+ 匹配,因为它不包含破折号字符 (-)。[a-zA-Z0-9_-]+ 会更正确。

该问题的最佳答案可能也是我在这里找到的唯一“官方”声明,groups.google.com/group/youtube-api-gdata/browse_thread/thread /...我们正式Promise YouTube 视频 ID 的标准长度为 11 个字符的文档。这是我们目前实施的内容之一,它可能会无限期地保持这种状态。但我们没有对此提供任何官方Promise,因此,请自行承担风险。”
2021-03-16 06:28:43
忘了说 (\w|-) 比 [a-zA-Z0-9_-] 短。:p;)
2021-03-17 06:28:43
您无法使用 + 验证 id 长度,{11} 会更正确。;)
2021-03-22 06:28:43
ids 固定为 11 个字符吗?将来可能会改变吗?
2021-03-28 06:28:43

@eyecatchup ubove 有一个优秀的正则表达式,但在 regexper.com 的帮助下,我看到他的正则表达式将传递任何 youtube url,其中 ?v 参数的值是任何单词或 - 符号重复 11 次。但是 youtube 特别将视频 ID 限制为 11 个字符,因此对他的正则表达式的修复是

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

比较他的正则表达式的可视化

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?$/

和我的修复

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

作为对未来 11 个字符限制的编辑,那么当前的正则表达式意味着任何单词或 - 都必须精确重复 11 次,我的修复是

/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11,})(?:\S+)?$/
似乎不再工作了。它也验证长度超过 11 个字符的视频 ID。
2021-04-09 06:28:43

改进@eyecatchUp 的正则表达式:

  1. 添加对 m.youtube.com 域的支持
  2. 通过@Nijikokun 添加对 youtube-nocookie.com 域的支持
^(?:https?:\/\/)?(?:(?:www|m)\.)?(?:youtu\.be\/|youtube(?:-nocookie)?\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$

正则表达式:

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