如何使用正则expression式查找string中的所有YouTubevideoID?

我有一个文本框,用户可以写任何东西。

例如:

Lorem Ipsum简直就是假文本。 http://www.youtube.com/watch?v=DUQi_R4SgWo印刷和排版行业。 Lorem Ipsum自从16世纪以来一直是业界的标准虚拟文本,当时一台不知名的打印机拿起了一个types的厨房,把它打成一个样板书。 它不仅存活了五个世纪,还有电子排版的飞跃,基本保持不变。 http://www.youtube.com/watch?v=A_6gNZCkajU&feature=relmfu它在20世纪60年代随着包含Lorem Ipsum段落的Letraset表单以及最近的包括Aldus PageMaker在内的桌面出版软件(包括Lorem Ipsum版本)的推出而得到了普及。

现在我想parsing它,find所有的YouTubevideourl和他们的ID。

任何想法如何工作?

YouTubevideourl可能会遇到各种格式:

  • 最新的短格式:http: http://youtu.be/NLqAF9hrVbY
  • iframe: http://www.youtube.com/embed/NLqAF9hrVbYhttp://www.youtube.com/embed/NLqAF9hrVbY
  • iframe(安全): https://www.youtube.com/embed/NLqAF9hrVbYhttps://www.youtube.com/embed/NLqAF9hrVbY
  • 对象参数: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US : http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US fs=1& http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US zh_CN
  • 对象embedded: http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US : http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US fs=1& http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
  • 请观看: http://www.youtube.com/watch?v=NLqAF9hrVbYhttp://www.youtube.com/watch?v=NLqAF9hrVbY
  • 用户: http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGohttp://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo
  • ytscreeningroom: http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8Ihttp://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I v http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I NRHVzbJVx8I
  • 任何/东西/去!: http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/2/PPS-8DMrAn4 : http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/2/PPS-8DMrAn4
  • 任何/子网域/太: http://gdata.youtube.com/feeds/api/videos/NLqAF9hrVbY : http://gdata.youtube.com/feeds/api/videos/NLqAF9hrVbY
  • 更多参数: http://www.youtube.com/watch?v=spDj54kf-vY&feature=g-vrec : http://www.youtube.com/watch?v=spDj54kf-vY&feature=g-vrec spDj54kf-vY&feature http://www.youtube.com/watch?v=spDj54kf-vY&feature=g-vrec g-vrec
  • 查询可能有点: http://www.youtube.com/watch?v=spDj54kf-vY&feature=youtu.be : http://www.youtube.com/watch?v=spDj54kf-vY&feature=youtu.be spDj54kf-vY&feature= http://www.youtube.com/watch?v=spDj54kf-vY&feature=youtu.be
  • nocookie域名: http://www.youtube-nocookie.comhttp://www.youtube-nocookie.com

这是一个带有注释的正则expression式的PHP函数,它匹配每个URL表单并将它们转换为链接(如果它们不是链接的话):

 // Linkify youtube URLs which are not already links. function linkifyYouTubeURLs($text) { $text = preg_replace('~(?#!js YouTubeId Rev:20160125_1800) # Match non-linked youtube URL in the wild. (Rev:20130823) https?:// # Required scheme. Either http or https. (?:[0-9A-Z-]+\.)? # Optional subdomain. (?: # Group host alternatives. youtu\.be/ # Either youtu.be, | youtube # or youtube.com or (?:-nocookie)? # youtube-nocookie.com \.com # followed by \S*? # Allow anything up to VIDEO_ID, [^\w\s-] # but char before ID is non-ID char. ) # End host alternatives. ([\w-]{11}) # $1: VIDEO_ID is exactly 11 chars. (?=[^\w-]|$) # Assert next char is non-ID or EOS. (?! # Assert URL is not pre-linked. [?=&+%\w.-]* # Allow URL (query) remainder. (?: # Group pre-linked alternatives. [\'"][^<>]*> # Either inside a start tag, | </a> # or inside <a> element text contents. ) # End recognized pre-linked alts. ) # End negative lookahead assertion. [?=&+%\w.-]* # Consume any URL (query) remainder. ~ix', '<a href="http://www.youtube.com/watch?v=$1">YouTube link: $1</a>', $text); return $text; } 

; //结束$ YouTubeId。

这里是一个与正则expression式完全相同的JavaScript版本(删除了注释):

 // Linkify youtube URLs which are not already links. function linkifyYouTubeURLs(text) { var re = /https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube(?:-nocookie)?\.com\S*?[^\w\s-])([\w-]{11})(?=[^\w-]|$)(?![?=&+%\w.-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/ig; return text.replace(re, '<a href="http://www.youtube.com/watch?v=$1">YouTube link: $1</a>'); } 

笔记:

  • URL的VIDEO_ID部分被捕获到唯一的捕获组: $1
  • 如果您知道您的文本不包含任何预先链接的URL,则可以安全地删除对此条件进行testing的否定性预测声明(声明以注释开头: “Assert URL未预先链接”有点正则expression式。
  • replacestring可以修改以适应。 上面提供的只是创build一个链接到通用的"http://www.youtube.com/watch?v=VIDEO_ID"风格的URL,并将链接文本设置为: "YouTube link: VIDEO_ID"

编辑2011-07-05:添加-连字符ID char类

编辑2011-07-17:修正了正则expression式消耗YouTube ID之后的URL的任何剩余部分(例如查询 )。 添加了'i' 忽略大小写修饰符。 将函数重命名为camelCase。 改进了预链接的前瞻性testing。

编辑2011-07-27:增加了新的“用户”和“ytscreeningroom”格式的YouTubeurl。

编辑2011-08-02:简化/泛化,以处理新的“任何东西/去”的YouTubeurl。

编辑2011-08-25:几个修改:

  • 增加了Javascript版本: linkifyYouTubeURLs()函数。
  • 以前的版本有scheme(HTTP协议)部分可选,因此将匹配无效的URL。 制定了计划的一部分要求。
  • 以前的版本在VIDEO_ID周围使用\b字边界锚。 但是,如果VIDEO_ID开始或以短划线结束,这将不起作用。 固定,以便它处理这种情况。
  • 改变了VIDEO_IDexpression式,使其必须正好是11个字符。
  • 如果之前的版本在VIDEO_ID后面有查询string,则无法排除预先链接的url。 改进了负面视图断言来解决这个问题。
  • 在字符类匹配查询string中添加了+%
  • 将PHP版本的正则expression式分隔符从: %更改为: ~
  • 添加了一些便笺的“注释”部分。

编辑2011-10-12: YouTube URL主机部分现在可能有任何子域名(不只是www. )。

编辑2012-05-01:消耗URL部分现在可以允许“ – ”。

编辑2013-08-23:添加@Mei提供的其他格式。 (查询部分可能有一个点。

编辑2013-11-30:增加@CRONUS提供的其他格式: youtube-nocookie.com

编辑2016-01-25:修正了正则expression式来处理CRONUS提供的错误情况。

以下是我曾经为提取YouTube和Vimeovideo密钥的项目撰写的一种方法:

 /** * strip important information out of any video link * * @param string link to a video on the hosters page * @return mixed FALSE on failure, array on success */ function getHostInfo ($vid_link) { // YouTube get video id if (strpos($vid_link, 'youtu')) { // Regular links if (preg_match('/(?<=v\=)([\w\d-_]+)/', $vid_link, $matches)) return array('host_name' => 'youtube', 'original_key' => $matches[0]); // Ajax hash tag links else if (preg_match('§([\d\w-_]+)$§i', $vid_link, $matches)) return array('host_name' => 'youtube', 'original_key' => $matches[0]); else return FALSE; } // Vimeo get video id elseif (strpos($vid_link, 'vimeo')) { if (preg_match('§(?<=/)([\d]+)§', $vid_link, $matches)) return array('host_name' => 'vimeo', 'original_key' => $matches[0]); else return FALSE; } else return FALSE; } 
  1. find一个将从文本中提取所有链接的正则expression式。 Google会帮助你。
  2. 循环所有链接并为每个链接调用getHostInfo()

虽然ridgerunner的答案是我的答案的基础,但他并没有解决所有的url,我不相信这是有能力的,因为YouTubeurl中的多个可能的VIDEO_ID匹配。 我的正则expression式包含了他作为最后手段的侵略性方法,但首先尝试所有常见匹配,这大大减less了URL后面错误匹配的可能性。

这个正则expression式:

 /https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com(?:\/embed\/|\/v\/|\/watch\?v=|\/ytscreeningroom\?v=|\/feeds\/api\/videos\/|\/user\S*[^\w\-\s]|\S*[^\w\-\s]))([\w\-]{11})[?=&+%\w-]*/ig; 

处理Ridgerunners示例中最初引用的所有情况,以及可能在URL中稍后有11个字符序列的任何url。 即:

http://www.youtube.com/watch?v=GUEZCxBcM78&feature=pyv&feature=pyv&ad=10059374899&kw=%2Bwingsuit

以下是一个可以testing所有示例YouTubeurl的工作示例:

http://jsfiddle.net/DJSwc/5/

尝试

 [^\s]*youtube\.com[^\s]*?v=([-\w]+)[^\s]* 

您将在第一个捕获组中findvideoID。 我不知道什么是有效的videoID? 此刻,我检查v=并捕获所有-A-Za-z0-9_

我在网上查了一下这个关于rubular的样本string。

使用:

 <?php // The YouTube URL string $youtube_url='http://www.youtube.com/watch?v=8VtUYvwktFQ'; // Use regex to get the video ID $regex='#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]/)[^&\n]+|(?<=v=)[^&\n]+#'; preg_match($regex, $youtube_url, $id); // Plug that into our HTML ?> 

好的,我做了我自己的function。 但是我相信这是非常低效的。 任何改进都欢迎:

 function get_youtube_videos($string) { $ids = array(); // Find all URLs preg_match_all('/(http|https)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/', $string, $links); foreach ($links[0] as $link) { if (preg_match('~youtube\.com~', $link)) { if (preg_match('/[^=]+=([^?]+)/', $link, $id)) { $ids[] = $id[1]; } } } return $ids; } 

我尝试了一个简单的expression式来获得唯一的videoid:

 [?&]v=([^&#]*) 

检查它在网上工作在这里在phpliveregex 。

原来的海报问:“我想parsing它,find所有的YouTubevideourl和他们的ID”。 我把上面最stream行的答案转换为preg_match,并返回videoID和URL。

从post中获取YouTubeurl和ID:

 $match[0] = Full URL $match[1] = video ID function get_youtube_id($input) { $input = preg_match('~https?://(?:[0-9A-Z-]+\.)?(?:youtu\.be/|youtube(?:-nocookie)?\.com\S*[^\w\s-])([\w-]{11})(?=[^\w-]|$)(?![?=&+%\w.-]*(?:[\'"][^<>]*>|</a>))[?=&+%\w.-]*~ix', $input, $match); return $match; } 

从string中轻松查找YouTube链接:

 function my_url_search($se_action_data) { $regex = '/https?\:\/\/[^\" ]+/i'; preg_match_all($regex, $se_action_data, $matches); $get_url=array_reverse($matches[0]); return array_unique($get_url); } echo my_url_search($se_action_data)