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

Posted

技术标签:

【中文标题】使用正则表达式的 jQuery Youtube URL 验证【英文标题】:jQuery Youtube URL Validation with regex 【发布时间】:2011-02-27 05:24:26 【问题描述】:

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

任何正文都有 javascript 正则表达式,用于验证下面列出的 YouTube 视频 URL 行。只是想知道这样的 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');

【问题讨论】:

你那里的那个正则表达式很麻烦。特别是匹配任何东西的.* 部分。这意味着它还将匹配以下 url:http://hackersrus.com/youtube-watch?v=a 哎呀!更改为 var matches = $('#videoUrl').val().match(/http:\/\/(?:www\.)?youtube.*watch\?v=([a-zA-Z0- 9\-_]+)/); if (matches) alert('valid'); else alert('无效'); 仍然是错误的,请参阅我的答案以获得完全正确的方式。 【参考方案1】:

终极 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://***.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's regex 乍一看还不错。但它:

    与包含短划线 (-) 的视频 ID 不匹配, 不验证 id 长度(v=aav=aaaaaaaaaaaaaaaaaa 返回有效), 并且根本不匹配安全 URL (https://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&amp;hl=en-US&amp;v=bQVoAWSP7k4

首先,请注意这根本不是URL。 RFC compliant URLs必须从方案开始! ;)

无论如何,为了匹配任何类型的表示指向 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\?.+&amp;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://***.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.$1替换为true即可。就是这样。

关于视频 ID 长度的最后一点说明:有人问 ID 是否有 11 个字符的固定长度?未来是否会改变?

这个问题的最佳答案可能也是我找到的唯一“官方”声明here 并说:“我在文档中没有看到我们正式承诺标准的任何地方YouTube 视频 ID 的长度为 11 个字符。这是我们当前实施的其中一项内容,并且可能会无限期地保持这种状态。但我们并未对此做出任何官方承诺,因此请自行承担风险。"

【讨论】:

你的正则表达式中的 youtube.com 部分可以匹配 youtubeXcom 之类的任何内容,你应该避开那个时期 如果网址是这样的怎么办; youtube.com/watch?gl=US&hl=en-US&v=bQVoAWSP7k4 @FizzBu​​zz 好吧,这根本不是一个有效的 URL(尽管(大多数)网络浏览器会接受这个输入)! RFC compliant URLs 必须提供一种通过描述其主要访问机制来定位资源的方法,它指的是始终以访问方案开头的有效 URI 语法。但是,您可以像这样在正则表达式中将该方案设为可选:var pattern = /^(?:https?:\/\/)?(?:www\.)?youtube\.com\/watch\?(?=.*v=((\w|-)11))(?:\S+)?$/; 这能回答您的问题吗? 如果您选择嵌入选项,您会得到youtu.be/_d6KuiuteIA 怎么样? 它给出以下警告“嵌套重复运算符'+'和'?'在正则表达式中被替换为 '*'"【参考方案2】:
^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+)?$

【讨论】:

很棒,但 youtube.com/watch?gl=US&hl=en-US&v=bQVoAWSP7k4 失败了 你的正则表达式中的 youtube.com 部分可以匹配 youtubeXcom 之类的任何内容,你应该避开那个时期 查看我的回答 (***.com/a/10315969/624466) 以获得改进的版本。 @Amarghosh ,能否请您告知 2 个网址中哪些是正确的?是不是很难解释?【参考方案3】:

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

【讨论】:

您不能使用 + 验证 id 长度,11 会更正确。 ;) 忘了说 (\w|-) 比 [a-zA-Z0-9_-] 短。 :p ;) ID 是否固定为 11 个字符?将来可能会改变吗? 该问题的最佳答案可能也是我在这里找到的唯一“官方”声明groups.google.com/group/youtube-api-gdata/browse_thread/thread/… 并说“我在文档中没有看到我们正式承诺YouTube 视频 ID 的标准长度为 11 个字符。这是我们当前实施的其中一项内容,并且可能会无限期地保持这种状态。但我们没有对此做出任何官方承诺,因此请自行承担风险。” 【参考方案4】:

@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。【参考方案5】:

改进@eyecatchUp 的正则表达式:

    添加对 m.youtube.com 域的支持 @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

【讨论】:

【参考方案6】:
 /* 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); 
  

【讨论】:

【参考方案7】:
function get_youtube_video_id_from_url(url)
    var code = url.match(/v=([^&#]5,)/)
    return (typeof code[1] == 'string') ? code[1] : false;

【讨论】:

完全错误。这甚至匹配var url = 'v=abcde';。此外,如果未找到匹配项,则生成 TypeError: Cannot read property '1' of null【参考方案8】:
function validYT(url) 
  var p = /^(?:https?:\/\/)?(?:www\.)?youtube\.com\/watch\?(?=.*v=((\w|-)11))(?:\S+)?$/;
  return (url.match(p)) ? RegExp.$1 : false;

【讨论】:

恭喜。您在上面发布了我的代码的过时版本。

以上是关于使用正则表达式的 jQuery Youtube URL 验证的主要内容,如果未能解决你的问题,请参考以下文章

jQuery选择器探究:正则表达式汇总

jQuery选择器探究:正则表达式汇总

YouTube ID 的正则表达式 [重复]

如何通过正则表达式提取 youtube 的 m3u8?

如何使用正则表达式在字符串中查找所有 YouTube 视频 ID?

如何使用正则表达式在字符串中查找所有 YouTube 视频 ID?