PHP Regex для получения идентификатора видео youtube?

может кто-нибудь показать мне, как получить идентификатор youtube из url независимо от того, какие другие переменные GET находятся в URL.

используйте это видео, например:http://www.youtube.com/watch?v=C4kxS1ksqtw&feature=related
между v= до следующего &

14 ответов


использовать parse_url() и parse_str ().

(вы можете использовать regexes практически для чего угодно, но они очень легко сделать ошибку, поэтому, если есть функции PHP специально для того, что вы пытаетесь выполнить, используйте их.)

parse_url берет строку и разрезает ее на массив, который имеет кучу информации. Вы можете работать с этим массивом, или можно указать один элемент, который вы хотите в качестве второго аргумента. В этом случае мы интересует запрос, который является PHP_URL_QUERY.

теперь у нас есть запрос, которая составляет v=C4kxS1ksqtw&feature=relate, но мы хотим только часть после v=. Для этого обратимся к parse_str который в основном работает как GET на строку. Он принимает строку и создает переменные, указанные в строке. В этом случае $v и это. Нас интересует только $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.Джейми Zawinski


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);

основываясь на комментарии бокора к ответу Энтони:

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

$matches[1] содержит не совпадают:

  • www.facebook.com?wtv=youtube.com/v/vidid

Это может быть очень легко сделать с помощью parse_str и parse_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";
}

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


исправлена на основе Как проверить идентификаторы видео 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));
}

мы знаем, что video 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"
}

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

(?<=\?v=)([a-zA-Z0-9_-]){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. Он потенциально может соответствовать большему количеству типов встраиваемых типов Youtube и URL-адресов:

$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


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

$vid = preg_replace('/[^\w\-\_].*$/', '', $vid);  // Strip trailing meuk.

Я знаю, что название потока относится к использованию регулярного выражения, но, как говорится в цитате Завинского, я действительно думаю, что здесь лучше избегать регулярных выражений. Вместо этого я бы рекомендовал эту функцию:

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-ed материал.


Это следующее будет работать для всех ссылок 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;
    ?>

просто нашел это в интернете: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;
}