如何使用正则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/NLqAF9hrVbY
:http://www.youtube.com/embed/NLqAF9hrVbY
- iframe(安全):
https://www.youtube.com/embed/NLqAF9hrVbY
:https://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=NLqAF9hrVbY
:http://www.youtube.com/watch?v=NLqAF9hrVbY
- 用户:
http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo
:http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo
- ytscreeningroom:
http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I
:http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I
vhttp://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&featurehttp://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.com
:http://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; }
- find一个将从文本中提取所有链接的正则expression式。 Google会帮助你。
- 循环所有链接并为每个链接调用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的工作示例:
尝试
[^\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)