PHP Regex для получения идентификатора видео youtube?
Может кто-нибудь показать мне, как получить идентификатор youtube из URL-адреса, независимо от того, какие другие переменные GET находятся в URL-адресе.
Используйте это видео, например: http://www.youtube.com/watch?v=C4kxS1ksqtw&feature=related
Итак, между v=
и перед следующим &
Ответы
Ответ 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
?>
Рабочий пример
Edit:
Хехе - спасибо Чарльзу. Это заставило меня рассмеяться, я никогда не видел цитату Завинского:
Some people, when confronted with a problem, think ‘I know, I’ll use regular expressions.’ Now they have two problems.
- Джейми Завински
Ответ 2
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);
Ответ 3
Основываясь на комментариях бокора на ответ Энтони:
preg_match("/^(?:http(?:s)?:\/\/)?(?:www\.)?(?:m\.)?(?:youtu\.be\/|youtube\.com\/(?:(?:watch)?\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)\/))([^\?&\"'>]+)/", $url, $matches);
$matches[1]
содержит vidid
Матчи:
Не соответствует:
- www.facebook.com?wtv=youtube.com/v/vidid
Ответ 4
Это можно легко выполнить с помощью parse_str и parse_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";
}
Ответ 5
SOLTUION Для любого типа ссылки!:
<?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
Ответ 6
исправлено на основе Как проверить видео идентификаторы YouTube?
<?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));
}
Ответ 7
Мы знаем, что идентификатор видео имеет длину 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"
}
Ответ 8
Следующее будет работать для всех ссылок 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;
?>
Ответ 9
if (preg_match('![?&]{1}v=([^&]+)!', $url . '&', $m))
$video_id = $m[1];
Ответ 10
(?<=\?v=)([a-zA-Z0-9_-]){11}
Это также должно сделать это.
Ответ 11
У меня было какое-то сообщение, которое я должен был зашифровать, чтобы получить идентификатор Youtube. Это оказалось в форме кода <iframe>
для встраивания Youtube.
<iframe src="http://www.youtube.com/embed/Zpk8pMz_Kgw?rel=0" frameborder="0" width="620" height="360"></iframe>
Следующий шаблон, который я получил из @rob выше. Фрагмент выполняет цикл foreach
после того, как совпадения найдены, а для дополнительного бонуса я связал его с изображением предварительного просмотра, найденным на Youtube. Это может потенциально соответствовать более типам типов и URL-адресов встраивания 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;
}
Профиль Роб: https://stackoverflow.com/users/149615/rob
Ответ 12
$vid = preg_replace('/^.*(\?|\&)v\=/', '', $url); // Strip all meuk before and including '?v=' or '&v='.
$vid = preg_replace('/[^\w\-\_].*$/', '', $vid); // Strip trailing meuk.
Ответ 13
Я знаю, что название потока относится к использованию регулярного выражения, но, как говорит цитата Завинского, я действительно думаю, что лучше избегать регулярных выражений. Вместо этого я рекомендую эту функцию:
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 всегда один и тот же, независимо от стиля URL-адреса, например.
-
http://www.youtube.com/watch?v=t_uW44Bsezg
-
http://www.youtube.com/watch?feature=endscreen&v=Id3xG4xnOfA&NR=1
- `И другая форма Ulr, в которой слово "embed/" помещается перед идентификатором...!!
и это может иметь место для встроенных и iframe
-элементов.
Ответ 14
Просто нашел это онлайн на 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;
}
Ответ 15
Я использовал данные из ответа Шона, но обобщил и немного сократил регулярное выражение. Основное отличие от этого в том, что он не проверяет действительный URL-адрес Youtube, а просто ищет идентификатор видео. Это означает, что он все равно вернет идентификатор видео для www.facebook.com?wtv=youtube.com/v/vidid
. Работает для всех тестовых случаев, но немного слабее. Следовательно, он выдаст ложное срабатывание для чего-то вроде https://www.twitter.com/watch?v=vidid
. Используйте этот метод, если данные супер противоречивы, в противном случае используйте более специфичные регулярные выражения или parse_url()
и parse_str()
.
preg_match("/([\?&\/]vi?|embed|\.be)[\/=]([\w-]+)/",$url,$matches);
print($matches[2]);
Ответ 16
Я думаю, что вы пытаетесь это сделать.
<?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>