如何使用正则表达式在字符串中查找所有 YouTube 视频 ID?
Posted
技术标签:
【中文标题】如何使用正则表达式在字符串中查找所有 YouTube 视频 ID?【英文标题】:How do I find all YouTube video ids in a string using a regex? 【发布时间】:2011-08-15 09:09:42 【问题描述】:我有一个文本字段,用户可以在其中写任何东西。
例如:
Lorem Ipsum 只是虚拟文本。 http://www.youtube.com/watch?v=DUQi_R4SgWo 印刷和排版的 行业。 Lorem Ipsum 一直是 业界标准的虚拟文本 自 1500 年代以来,当一个未知的 打印机拿了一个类型的厨房和 把它炒作一个类型标本 书。它不仅存活了五 百年,也跃进 电子排版,剩余 基本不变。 http://www.youtube.com/watch?v=A_6gNZCkajU&feature=relmfu 它在 1960 年代流行于 Letraset 表的发布 包含 Lorem Ipsum 段落,以及 最近与桌面出版 像 Aldus PageMaker 这样的软件 包括 Lorem Ipsum 的版本。
现在我想解析它并找到所有 YouTube 视频 URL 及其 ID。
知道它是如何工作的吗?
【问题讨论】:
javascript REGEX: How to get youtube video id from URL?的可能重复 【参考方案1】:可能会遇到多种格式的 YouTube 视频 URL:
最新短格式:http://youtu.be/NLqAF9hrVbY
iframe:http://www.youtube.com/embed/NLqAF9hrVbY
iframe(安全):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
观看:http://www.youtube.com/watch?v=NLqAF9hrVbY
用户:http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo
yt 放映室:http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I
任何/事情/去!:http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/2/PPS-8DMrAn4
任何/子域/也: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=youtu.be
nocookie 域:http://www.youtube-nocookie.com
这是一个带有注释正则表达式的 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。
这是一个 JavaScript 版本,其正则表达式完全相同(删除了 cmets):
// 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,则可以安全地删除测试此条件的否定前瞻断言(以注释开头的断言:“断言 URL 未预链接.") 这将在一定程度上加快正则表达式的速度。
可以修改替换字符串以适合。上面提供的只是创建一个指向通用 "http://www.youtube.com/watch?v=VIDEO_ID"
样式 URL 的链接,并将链接文本设置为:"YouTube link: VIDEO_ID"
。
2011-07-05 编辑:在 ID char 类中添加了-
连字符
2011 年 7 月 17 日编辑: 修复了正则表达式以使用 YouTube ID 后面的 URL 的任何剩余部分(例如 查询)。添加了'i'
ignore-case 修饰符。将函数重命名为 camelCase。改进了预链接的前瞻测试。
2011 年 7 月 27 日编辑:添加了新的 YouTube 网址“用户”和“ytscreeningroom”格式。
2011-08-02 编辑:简化/通用化以处理新的“any/thing/goes”YouTube URL。
编辑 2011-08-25: 几处修改:
添加了 Javascript 版本:linkifyYouTubeURLs()
函数。
先前版本的方案(HTTP 协议)部分是可选的,因此会匹配无效的 URL。使方案部分成为必需的。
以前的版本在 VIDEO_ID 周围使用了\b
字边界锚。但是,如果 VIDEO_ID 以 -
破折号开头或结尾,这将不起作用。已修复,以便处理这种情况。
更改了 VIDEO_ID 表达式,使其长度必须正好为 11 个字符。
如果 VIDEO_ID 后面有查询字符串,则以前的版本无法排除预链接 URL。改进了否定前瞻断言以解决此问题。
在字符类匹配查询字符串中添加了+
和%
。
将 PHP 版本正则表达式分隔符从:%
更改为:~
。
添加了带有一些方便注释的“注释”部分。
编辑 2011-10-12:YouTube URL 主机部分现在可以有任何子域(不仅仅是www.
)。
编辑 2012-05-01:使用 URL 部分现在可以允许使用“-”。
2013-08-23 编辑:添加了@Mei 提供的附加格式。 (查询部分可能有一个.
点。
2013-11-30 编辑:添加了@CRONUS 提供的其他格式:youtube-nocookie.com
。
编辑 2016-01-25: 修复了正则表达式以处理 CRONUS 提供的错误情况。
【讨论】:
我还没有看到规范,但我确实搜索了一个。我刚刚注意到互联网上一些链接中的破折号。例如:youtube.com/watch?v=CLPk-6_xgiY @littleFluffyKitty:感谢您的提醒。已更新答案以包含连字符作为有效的 ID 字符。 @ridgerunner:如果您对编辑没有信心,可以回滚。此外,就像在***上一样,整个历史都与您的学分一起保存。随着时间的推移,我看到你真的很喜欢答案,所以把你丢在这里太可惜了。 这是一个不起作用的方法:youtube.com/watch?v=E1IPnnttL9k&feature=youtu.be 这很好用,但是这个(新的?)查询字符串参数失败了:feature=youtu.be。将 [?=&+%\w-]* 更改为 [?=&+%\w-\.]* 在“使用剩余 url”行上就可以了。谢谢!【参考方案2】:这是我曾经为一个提取 YouTube 和 Vimeo 视频密钥的项目编写的方法:
/**
* 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;
-
查找将从文本中提取所有链接的正则表达式。 Google 会在这方面为您提供帮助。
循环所有链接并为每个链接调用 getHostInfo()
【讨论】:
非常感谢!轻微的 modif(strpos($vid_link, 'youtu'))
将捕获除了常见 url 之外的短 url youtu.be
。
不客气。感谢您的更新,我在更改中进行了编辑。在旁注中,ridgerunner 的正则表达式似乎是真正的交易,我建议在我的简单事情上使用它。欢呼
正是我想要的。看准队友! +1【参考方案3】:
虽然 ridgerunner 的回答是我回答的基础,但他并不能解决所有网址,而且我不相信它能够解决,因为 YouTube 网址中有多个可能匹配的 VIDEO_ID
。我的正则表达式将他的激进方法作为最后的手段,但首先尝试所有常见的匹配,从而大大降低了 URL 稍后出现错误匹配的可能性。
这个正则表达式:
/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
这是一个测试所有示例 YouTube 网址的工作示例:
http://jsfiddle.net/DJSwc/5/
【讨论】:
【参考方案4】:试试
[^\s]*youtube\.com[^\s]*?v=([-\w]+)[^\s]*
您将在第一个捕获组中找到视频 ID。我不知道什么是有效的视频 ID?目前我检查v=
并捕获所有-A-Za-z0-9_
。
我使用您的示例字符串在线检查了here on rubular。
【讨论】:
【参考方案5】:用途:
<?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
?>
【讨论】:
【参考方案6】:好的,我自己做了一个函数。但我认为这是非常低效的。 欢迎任何改进:
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;
【讨论】:
如果您只寻找来自 youtube.com 的链接,为什么要首先建立一个包含所有链接的列表?而且我认为没有必要使用 3 种不同的正则表达式。【参考方案7】:我尝试了一个简单的表达式来只获取videoid:
[?&]v=([^&#]*)
在线查看here at phpliveregex。
【讨论】:
【参考方案8】:原发帖人问“我想解析它并找到所有 YouTube 视频 URL 及其 ID。”我将上面最受欢迎的答案切换为 preg_match 并返回了视频 ID 和 URL。
从帖子中获取 YouTube URL 和 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;
【讨论】:
【参考方案9】:从字符串中轻松找到 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)
【讨论】:
这不仅适用于 YoutTube,它还会匹配内容中的其他 url。【参考方案10】:String urlid="" ;
String url="http://www.youtube.com/watch?v=0zM4nApSvMg#t=0m10s";
Pattern pattern =Pattern.compile("(?:http|https|)(?::\\/\\/|)(?:www.|)(?:youtu\\.be\\/|youtube\\.com(?:\\/embed\\/|\\/v\\/|\\/watch\\?v=|\\/ytscreeningroom\\?v=|\\/feeds\\/api\\/videos\\/|\\/user\\\\S*[^\\w\\-\\s]|\\S*[^\\w\\-\\s]))([\\w\\-\\_]11)[a-z0-9;:@#?&%=+\\/\\$_.-]*");
Matcher result = pattern.matcher(url);
if (result.find())
urlid=result.group(1);
Java 中的这段代码对目前所有的 youtube 网址都适用。
【讨论】:
以上是关于如何使用正则表达式在字符串中查找所有 YouTube 视频 ID?的主要内容,如果未能解决你的问题,请参考以下文章
如何创建正则表达式来查找 JS 文件(或 JSON)中的所有字符串
如何使用正则表达式查找具有特定起始字符串的所有匹配项? [复制]