PHP 正则获得 youtube 视频 ID?

有没有人能告诉我如何得到的 youtube 标识出一个网址,而不管什么其他 GET 变量在网址。

使用这个视频例如: http://www.youtube.com/watch?v=C4kxS1ksqtw&feature=related
所以在 v=和下一个 &之间

205090 次浏览
if (preg_match('![?&]{1}v=([^&]+)!', $url . '&', $m))
$video_id = $m[1];

使用 parse _ url () Parse _ str ()

(您可以将正则表达式用于任何事情,但是它们很容易出错,所以如果有专门针对您要完成的任务的 PHP 函数,请使用它们。)

Parse _ url 获取一个字符串,并将其分割成一个包含大量信息的数组。可以使用此数组,也可以将所需的一个项指定为第二个参数。在本例中,我们感兴趣的是查询,即 PHP_URL_QUERY

现在我们有了查询,它是 v=C4kxS1ksqtw&feature=relate,但是我们只需要 v=之后的部分。为此,我们转向 parse_str,它基本上像字符串上的 GET一样工作。它接受一个字符串并创建字符串中指定的变量。在这种情况下,创建 $v$feature。我们只对 $v感兴趣。

为了安全起见,您不希望仅仅将 parse_url中的所有变量存储在您的名称空间中(参见 mellowsoon 的注释)。相反,将变量存储为数组的元素,这样就可以控制存储的变量,而且不能意外地覆盖现有变量。

把所有东西放在一起,我们有:

<?php
$url = "http://www.youtube.com/watch?v=C4kxS1ksqtw&feature=relate";
parse_str( parse_url( $url, PHP_URL_QUERY ), $my_array_of_vars );
echo $my_array_of_vars['v'];
// Output: C4kxS1ksqtw
?>

举个例子


编辑:

呵呵-谢谢查尔斯。这让我笑了,我以前从来没有见过 Zawinski 引用:

杰米 · 扎文斯基

(?<=\?v=)([a-zA-Z0-9_-]){11}

这个也可以。

$vid = preg_replace('/^.*(\?|\&)v\=/', '', $url);  // Strip all meuk before and including '?v=' or '&v='.


$vid = preg_replace('/[^\w\-\_].*$/', '', $vid);  // Strip trailing meuk.
preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=v\/)[^&\n]+|(?<=v=)[^&\n]+|(?<=youtu.be/)[^&\n]+#", $url, $matches);

这个可以解释

youtube.com/v/{vidid}
youtube.com/vi/{vidid}
youtube.com/?v={vidid}
youtube.com/?vi={vidid}
youtube.com/watch?v={vidid}
youtube.com/watch?vi={vidid}
youtu.be/{vidid}

我稍微改进了一下,以支持: Http://www.youtube.com/v/5xadesocujo?feature=autoshare&version=3&autohide=1&autoplay=1

我现在用的台词是:

preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=v\/)[^&\n]+(?=\?)|(?<=v=)[^&\n]+|(?<=youtu.be/)[^&\n]+#", $link, $matches);

我有一些帖子的内容,我必须加密整个得到的 Youtube ID 了。它碰巧是以 Youtube 提供的 <iframe>嵌入代码的形式出现的。

 <iframe src="http://www.youtube.com/embed/Zpk8pMz_Kgw?rel=0" frameborder="0" width="620" height="360"></iframe>

以下是我从上面的“ Rob”得到的模式。一旦找到匹配项,这个代码片段就会执行 foreach循环,为了获得额外的好处,我将它链接到 Youtube 上的预览图片。它可能会匹配更多类型的 Youtube 嵌入类型和网址:

$pattern = '#(?<=(?:v|i)=)[a-zA-Z0-9-]+(?=&)|(?<=(?:v|i)\/)[^&\n]+|(?<=embed\/)[^"&\n]+|(?<=‌​(?:v|i)=)[^&\n]+|(?<=youtu.be\/)[^&\n]+#';


preg_match_all($pattern, $post_content, $matches);


foreach ($matches as $match) {
$img = "<img src='http://img.youtube.com/vi/".str_replace('?rel=0','', $match[0])."/0.jpg' />";
break;
}

Rob 的资料: https://stackoverflow.com/users/149615/rob

我知道这个线程的标题指的是正则表达式的使用,但正如 Zawinski 所说,我真的认为避免使用正则表达式是最好的。我推荐这个函数:

function get_youtube_id($url)
{
if (strpos( $url,"v=") !== false)
{
return substr($url, strpos($url, "v=") + 2, 11);
}
elseif(strpos( $url,"embed/") !== false)
{
return substr($url, strpos($url, "embed/") + 6, 11);
}


}

我建议这样做,因为 YouTube 视频的 ID 总是相同的,独立于 URL 的样式,例如。

  • http://www.youtube.com/watch?v=t_uW44Bsezg
  • http://www.youtube.com/watch?feature=endscreen&v=Id3xG4xnOfA&NR=1
  • “以及其他将‘ embed/’这个词放在本我之前的 Ulr 形式... ! !”!

这可能是嵌入式和 iframe教材的情况。

根据博科对安东尼回答的评论:

preg_match("/^(?:http(?:s)?:\/\/)?(?:www\.)?(?:m\.)?(?:youtu\.be\/|youtube\.com\/(?:(?:watch)?\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user|shorts)\/))([^\?&\"'>]+)/", $url, $matches);

$matches[1]包含视频

比赛:

不匹配:

这可以很容易地完成使用 Parse _ strParse _ url,是更可靠的,在我看来。

我的函数支持以下 URL:

还包括函数下面的测试。

/**
* Get Youtube video ID from URL
*
* @param string $url
* @return mixed Youtube video ID or FALSE if not found
*/
function getYoutubeIdFromUrl($url) {
$parts = parse_url($url);
if(isset($parts['query'])){
parse_str($parts['query'], $qs);
if(isset($qs['v'])){
return $qs['v'];
}else if(isset($qs['vi'])){
return $qs['vi'];
}
}
if(isset($parts['path'])){
$path = explode('/', trim($parts['path'], '/'));
return $path[count($path)-1];
}
return false;
}
// Test
$urls = array(
'http://youtube.com/v/dQw4w9WgXcQ?feature=youtube_gdata_player',
'http://youtube.com/vi/dQw4w9WgXcQ?feature=youtube_gdata_player',
'http://youtube.com/?v=dQw4w9WgXcQ&feature=youtube_gdata_player',
'http://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=youtube_gdata_player',
'http://youtube.com/?vi=dQw4w9WgXcQ&feature=youtube_gdata_player',
'http://youtube.com/watch?v=dQw4w9WgXcQ&feature=youtube_gdata_player',
'http://youtube.com/watch?vi=dQw4w9WgXcQ&feature=youtube_gdata_player',
'http://youtu.be/dQw4w9WgXcQ?feature=youtube_gdata_player'
);
foreach($urls as $url){
echo $url . ' : ' . getYoutubeIdFromUrl($url) . "\n";
}

解决方案: 适用于任何链接类型:

<?php
function get_youtube_id_from_url($url)  {
preg_match('/(http(s|):|)\/\/(www\.|)yout(.*?)\/(embed\/|watch.*?v=|)([a-z_A-Z0-9\-]{11})/i', $url, $results);    return $results[6];
}




echo get_youtube_id_from_url('http://www.youtube.com/watch?var1=blabla#v=GvJehZx3eQ1$var2=bla');
// or                   http://youtu.be/GvJehZx3eQ1
// or                   http://www.youtube.com/embed/GvJehZx3eQ1
// or                   http://www.youtu.be/GvJehZx3eQ1/blabla?xyz
?>

产出: GvJehZx3eQ1

我们知道视频 ID 是11个字符长度,可以在前面加上 v=vi=v/vi/youtu.be/。最简单的方法是:

<?php
$youtube = 'http://youtube.com/v/dQw4w9WgXcQ?feature=youtube_gdata_player
http://youtube.com/vi/dQw4w9WgXcQ?feature=youtube_gdata_player
http://youtube.com/?v=dQw4w9WgXcQ&feature=youtube_gdata_player
http://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=youtube_gdata_player
http://youtube.com/?vi=dQw4w9WgXcQ&feature=youtube_gdata_player
http://youtube.com/watch?v=dQw4w9WgXcQ&feature=youtube_gdata_player
http://youtube.com/watch?vi=dQw4w9WgXcQ&feature=youtube_gdata_player
http://youtu.be/dQw4w9WgXcQ?feature=youtube_gdata_player';


preg_match_all("#(?<=v=|v\/|vi=|vi\/|youtu.be\/)[a-zA-Z0-9_-]{11}#", $youtube, $matches);


var_dump($matches[0]);

输出:

array(8) {
[0]=>
string(11) "dQw4w9WgXcQ"
[1]=>
string(11) "dQw4w9WgXcQ"
[2]=>
string(11) "dQw4w9WgXcQ"
[3]=>
string(11) "dQw4w9WgXcQ"
[4]=>
string(11) "dQw4w9WgXcQ"
[5]=>
string(11) "dQw4w9WgXcQ"
[6]=>
string(11) "dQw4w9WgXcQ"
[7]=>
string(11) "dQw4w9WgXcQ"
}

基于 如何验证 youtube 视频 ID?的固定

<?php


$links = [
"youtube.com/v/tFad5gHoBjY",
"youtube.com/vi/tFad5gHoBjY",
"youtube.com/?v=tFad5gHoBjY",
"youtube.com/?vi=tFad5gHoBjY",
"youtube.com/watch?v=tFad5gHoBjY",
"youtube.com/watch?vi=tFad5gHoBjY",
"youtu.be/tFad5gHoBjY",
"http://youtu.be/qokEYBNWA_0?t=30m26s",
"youtube.com/v/vidid",
"youtube.com/vi/vidid",
"youtube.com/?v=vidid",
"youtube.com/?vi=vidid",
"youtube.com/watch?v=vidid",
"youtube.com/watch?vi=vidid",
"youtu.be/vidid",
"youtube.com/embed/vidid",
"http://youtube.com/v/vidid",
"http://www.youtube.com/v/vidid",
"https://www.youtube.com/v/vidid",
"youtube.com/watch?v=vidid&wtv=wtv",
"http://www.youtube.com/watch?dev=inprogress&v=vidid&feature=related",
"youtube.com/watch?v=7HCZvhRAk-M"
];


foreach($links as $link){
preg_match("#([\/|\?|&]vi?[\/|=]|youtu\.be\/|embed\/)([a-zA-Z0-9_-]+)#", $link, $matches);
var_dump(end($matches));
}

刚在 http://snipplr.com/view/62238/get-youtube-video-id-very-robust/网上找到这个

function getYouTubeId($url) {
// Format all domains to http://domain for easier URL parsing
str_replace('https://', 'http://', $url);
if (!stristr($url, 'http://') && (strlen($url) != 11)) {
$url = 'http://' . $url;
}
$url = str_replace('http://www.', 'http://', $url);


if (strlen($url) == 11) {
$code = $url;
} else if (preg_match('/http:\/\/youtu.be/', $url)) {
$url = parse_url($url, PHP_URL_PATH);
$code = substr($url, 1, 11);
} else if (preg_match('/watch/', $url)) {
$arr = parse_url($url);
parse_str($url);
$code = isset($v) ? substr($v, 0, 11) : false;
} else if (preg_match('/http:\/\/youtube.com\/v/', $url)) {
$url = parse_url($url, PHP_URL_PATH);
$code = substr($url, 3, 11);
} else if (preg_match('/http:\/\/youtube.com\/embed/', $url, $matches)) {
$url = parse_url($url, PHP_URL_PATH);
$code = substr($url, 7, 11);
} else if (preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]/)[^&\n]+|(?<=v=)[^&\n]+#", $url, $matches) ) {
$code = substr($matches[0], 0, 11);
} else {
$code = false;
}


if ($code && (strlen($code) < 11)) {
$code = false;
}


return $code;
}

以下内容适用于所有的 youtube 链接

<?php
// Here is a sample of the URLs this regex matches: (there can be more content after the given URL that will be ignored)
// http://youtu.be/dQw4w9WgXcQ
// http://www.youtube.com/embed/dQw4w9WgXcQ
// http://www.youtube.com/watch?v=dQw4w9WgXcQ
// http://www.youtube.com/?v=dQw4w9WgXcQ
// http://www.youtube.com/v/dQw4w9WgXcQ
// http://www.youtube.com/e/dQw4w9WgXcQ
// http://www.youtube.com/user/username#p/u/11/dQw4w9WgXcQ
// http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/0/dQw4w9WgXcQ
// http://www.youtube.com/watch?feature=player_embedded&v=dQw4w9WgXcQ
// http://www.youtube.com/?feature=player_embedded&v=dQw4w9WgXcQ
// It also works on the youtube-nocookie.com URL with the same above options.
// It will also pull the ID from the URL in an embed code (both iframe and object tags)


$url = "https://www.youtube.com/watch?v=v2_MLFVdlQM";


preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $url, $match);


$youtube_id = $match[1];


echo $youtube_id;
?>

我使用了来自 Shawn 的回答的数据,但是对正则表达式进行了一些推广和缩短。这个版本的关键区别在于它不会测试有效的 Youtube URL,它只会查找视频 ID。这意味着它仍然会返回 www.facebook.com?wtv=youtube.com/v/vidid的视频 ID。适用于所有的测试用例,但是比较宽松。因此,它会输出一个类似于 https://www.twitter.com/watch?v=vidid的假阳性。如果数据非常不一致,请使用此方法,否则请使用更具体的正则表达式或 parse_url()parse_str()

preg_match("/([\?&\/]vi?|embed|\.be)[\/=]([\w-]+)/",$url,$matches);
print($matches[2]);

我觉得你是故意的。

<?php
$video = 'https://www.youtube.com/watch?v=u00FY9vADfQ';
$parsed_video = parse_url($video, PHP_URL_QUERY);
parse_str($parsed_video, $arr);
?>
<iframe
src="https://www.youtube.com/embed/<?php echo $arr['v'];  ?>"
frameborder="0">
</iframe>

如果我想从一个充满其他字符的字符串中提取一个 youtueurl,会怎么样呢:

我们必须承担所有的痛苦,承担所有的责任,承担所有的责任,承担所有的责任,承担所有的责任,承担所有的责任。至少,我们应该知道这样做的后果是什么。(德语)(德语)(德语)(德语)(德语)(德语)(德语)。除非有罪,否则我们将承担责任。

然后从那根线得到 https://www.youtube.com/watch?v=cPW9Y94BJI0

为了在捕获组中提取 id,下面的表达式或者它的一些派生形式也可能是一个选项:

(?im)\b(?:https?:\/\/)?(?:w{3}\.)?youtu(?:be)?\.(?:com|be)\/(?:(?:\??v=?i?=?\/?)|watch\?vi?=|watch\?.*?&v=|embed\/|)([A-Z0-9_-]{11})\S*(?=\s|$)

演示

测试

$re = '/(?im)\b(?:https?:\/\/)?(?:w{3}\.)?youtu(?:be)?\.(?:com|be)\/(?:(?:\??v=?i?=?\/?)|watch\?vi?=|watch\?.*?&v=|embed\/|)([A-Z0-9_-]{11})\S*(?=\s|$)/';
$str = 'http://youtube.com/v/tFad5gHoBjY
https://youtube.com/vi/tFad5gHoBjY
http://www.youtube.com/?v=tFad5gHoBjY
http://www.youtube.com/?vi=tFad5gHoBjY
https://www.youtube.com/watch?v=tFad5gHoBjY
youtube.com/watch?vi=tFad5gHoBjY
youtu.be/tFad5gHoBjY
http://youtu.be/qokEYBNWA_0?t=30m26s
youtube.com/v/7HCZvhRAk-M
youtube.com/vi/7HCZvhRAk-M
youtube.com/?v=7HCZvhRAk-M
youtube.com/?vi=7HCZvhRAk-M
youtube.com/watch?v=7HCZvhRAk-M
youtube.com/watch?vi=7HCZvhRAk-M
youtu.be/7HCZvhRAk-M
youtube.com/embed/7HCZvhRAk-M
http://youtube.com/v/7HCZvhRAk-M
http://www.youtube.com/v/7HCZvhRAk-M
https://www.youtube.com/v/7HCZvhRAk-M
youtube.com/watch?v=7HCZvhRAk-M&wtv=wtv
http://www.youtube.com/watch?dev=inprogress&v=7HCZvhRAk-M&feature=related
youtube.com/watch?v=7HCZvhRAk-M
http://youtube.com/v/dQw4w9WgXcQ?feature=youtube_gdata_player
http://youtube.com/vi/dQw4w9WgXcQ?feature=youtube_gdata_player
http://youtube.com/?v=dQw4w9WgXcQ&feature=youtube_gdata_player
http://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=youtube_gdata_player
http://youtube.com/?vi=dQw4w9WgXcQ&feature=youtube_gdata_player
http://youtube.com/watch?v=dQw4w9WgXcQ&feature=youtube_gdata_player
http://youtube.com/watch?vi=dQw4w9WgXcQ&feature=youtube_gdata_player
http://youtu.be/dQw4w9WgXcQ?feature=youtube_gdata_player';


preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);


var_dump($matches);

输出

array(30) {
[0]=>
array(2) {
[0]=>
string(32) "http://youtube.com/v/tFad5gHoBjY"
[1]=>
string(11) "tFad5gHoBjY"
}
[1]=>
array(2) {
[0]=>
string(34) "https://youtube.com/vi/tFad5gHoBjY"
[1]=>
string(11) "tFad5gHoBjY"
}
[2]=>
array(2) {
[0]=>
string(37) "http://www.youtube.com/?v=tFad5gHoBjY"
[1]=>
string(11) "tFad5gHoBjY"
}
[3]=>
array(2) {
[0]=>
string(38) "http://www.youtube.com/?vi=tFad5gHoBjY"
[1]=>
string(11) "tFad5gHoBjY"
}
[4]=>
array(2) {
[0]=>
string(43) "https://www.youtube.com/watch?v=tFad5gHoBjY"
[1]=>
string(11) "tFad5gHoBjY"
}
[5]=>
array(2) {
[0]=>
string(32) "youtube.com/watch?vi=tFad5gHoBjY"
[1]=>
string(11) "tFad5gHoBjY"
}
[6]=>
array(2) {
[0]=>
string(20) "youtu.be/tFad5gHoBjY"
[1]=>
string(11) "tFad5gHoBjY"
}
[7]=>
array(2) {
[0]=>
string(27) "http://youtu.be/qokEYBNWA_0"
[1]=>
string(11) "qokEYBNWA_0"
}
[8]=>
array(2) {
[0]=>
string(25) "youtube.com/v/7HCZvhRAk-M"
[1]=>
string(11) "7HCZvhRAk-M"
}
[9]=>
array(2) {
[0]=>
string(26) "youtube.com/vi/7HCZvhRAk-M"
[1]=>
string(11) "7HCZvhRAk-M"
}
[10]=>
array(2) {
[0]=>
string(26) "youtube.com/?v=7HCZvhRAk-M"
[1]=>
string(11) "7HCZvhRAk-M"
}
[11]=>
array(2) {
[0]=>
string(27) "youtube.com/?vi=7HCZvhRAk-M"
[1]=>
string(11) "7HCZvhRAk-M"
}
[12]=>
array(2) {
[0]=>
string(31) "youtube.com/watch?v=7HCZvhRAk-M"
[1]=>
string(11) "7HCZvhRAk-M"
}
[13]=>
array(2) {
[0]=>
string(32) "youtube.com/watch?vi=7HCZvhRAk-M"
[1]=>
string(11) "7HCZvhRAk-M"
}
[14]=>
array(2) {
[0]=>
string(20) "youtu.be/7HCZvhRAk-M"
[1]=>
string(11) "7HCZvhRAk-M"
}
[15]=>
array(2) {
[0]=>
string(29) "youtube.com/embed/7HCZvhRAk-M"
[1]=>
string(11) "7HCZvhRAk-M"
}
[16]=>
array(2) {
[0]=>
string(32) "http://youtube.com/v/7HCZvhRAk-M"
[1]=>
string(11) "7HCZvhRAk-M"
}
[17]=>
array(2) {
[0]=>
string(36) "http://www.youtube.com/v/7HCZvhRAk-M"
[1]=>
string(11) "7HCZvhRAk-M"
}
[18]=>
array(2) {
[0]=>
string(37) "https://www.youtube.com/v/7HCZvhRAk-M"
[1]=>
string(11) "7HCZvhRAk-M"
}
[19]=>
array(2) {
[0]=>
string(31) "youtube.com/watch?v=7HCZvhRAk-M"
[1]=>
string(11) "7HCZvhRAk-M"
}
[20]=>
array(2) {
[0]=>
string(57) "http://www.youtube.com/watch?dev=inprogress&v=7HCZvhRAk-M"
[1]=>
string(11) "7HCZvhRAk-M"
}
[21]=>
array(2) {
[0]=>
string(31) "youtube.com/watch?v=7HCZvhRAk-M"
[1]=>
string(11) "7HCZvhRAk-M"
}
[22]=>
array(2) {
[0]=>
string(32) "http://youtube.com/v/dQw4w9WgXcQ"
[1]=>
string(11) "dQw4w9WgXcQ"
}
[23]=>
array(2) {
[0]=>
string(33) "http://youtube.com/vi/dQw4w9WgXcQ"
[1]=>
string(11) "dQw4w9WgXcQ"
}
[24]=>
array(2) {
[0]=>
string(33) "http://youtube.com/?v=dQw4w9WgXcQ"
[1]=>
string(11) "dQw4w9WgXcQ"
}
[25]=>
array(2) {
[0]=>
string(42) "http://www.youtube.com/watch?v=dQw4w9WgXcQ"
[1]=>
string(11) "dQw4w9WgXcQ"
}
[26]=>
array(2) {
[0]=>
string(34) "http://youtube.com/?vi=dQw4w9WgXcQ"
[1]=>
string(11) "dQw4w9WgXcQ"
}
[27]=>
array(2) {
[0]=>
string(38) "http://youtube.com/watch?v=dQw4w9WgXcQ"
[1]=>
string(11) "dQw4w9WgXcQ"
}
[28]=>
array(2) {
[0]=>
string(39) "http://youtube.com/watch?vi=dQw4w9WgXcQ"
[1]=>
string(11) "dQw4w9WgXcQ"
}
[29]=>
array(2) {
[0]=>
string(27) "http://youtu.be/dQw4w9WgXcQ"
[1]=>
string(11) "dQw4w9WgXcQ"
}
}

如果您希望简化/修改/探索这个表达式,它已经在 Regex101.com的右上面板中进行了解释。如果您愿意,您还可以在 这个链接中观察它如何与一些样本输入进行匹配。


正交电路

Jex.im 可视化正则表达式:

enter image description here


使用以下代码:

$url = "http://www.youtube.com/watch?v=C4kxS1ksqtw&feature=related";
$parse = parse_url($url, PHP_URL_QUERY);
parse_str($parse, $output);
echo $output['watch'];

结果: C4kxS1ksqtw