2012-03-07 54 views
8

让我们这些网址为例:正则表达式来从任何YouTube网址YouTube的视频ID

  1. http://www.youtube.com/watch?v=8GqqjVXhfMU&feature=youtube_gdata_player
  2. http://www.youtube.com/watch?v=8GqqjVXhfMU

这个PHP功能将无法正常获取的ID在情况1,但情况2.情况1非常普遍,其中任何情况都可能落后于YouTube ID。

/** 
* get YouTube video ID from URL 
* 
* @param string $url 
* @return string YouTube video id or FALSE if none found. 
*/ 
function youtube_id_from_url($url) { 
    $pattern = 
     '%^# Match any YouTube URL 
     (?:https?://)? # Optional scheme. Either http or https 
     (?:www\.)?  # Optional www subdomain 
     (?:    # Group host alternatives 
      youtu\.be/ # Either youtu.be, 
     | youtube\.com # or youtube.com 
      (?:   # Group path alternatives 
      /embed/  # Either /embed/ 
      | /v/   # or /v/ 
      | /watch\?v= # or /watch\?v= 
     )    # End path alternatives. 
     )    # End host alternatives. 
     ([\w-]{10,12}) # Allow 10-12 for 11 char YouTube id. 
     $%x' 
     ; 
    $result = preg_match($pattern, $url, $matches); 
    if (false !== $result) { 
     return $matches[1]; 
    } 
    return false; 
} 

我在想什么是必须有一种方法,我可以只认准的“v =”,无论它位于URL,之后采取的字符。以这种方式,不需要复杂的RegEx。这是基地?任何想法的起点?

+0

我认为这种模式的主要问题只是模式结束时的$,它将模式锚定在被测试字符串的末尾。这就是案例1不匹配的原因,因为它不以ID结束。 – Bendoh 2013-06-27 20:09:47

回答

27
if (preg_match('/youtube\.com\/watch\?v=([^\&\?\/]+)/', $url, $id)) { 
    $values = $id[1]; 
} else if (preg_match('/youtube\.com\/embed\/([^\&\?\/]+)/', $url, $id)) { 
    $values = $id[1]; 
} else if (preg_match('/youtube\.com\/v\/([^\&\?\/]+)/', $url, $id)) { 
    $values = $id[1]; 
} else if (preg_match('/youtu\.be\/([^\&\?\/]+)/', $url, $id)) { 
    $values = $id[1]; 
} 
else if (preg_match('/youtube\.com\/verify_age\?next_url=\/watch%3Fv%3D([^\&\?\/]+)/', $url, $id)) { 
    $values = $id[1]; 
} else { 
// not an youtube video 
} 

这是我用来从YouTube网址中提取的ID。我认为它适用于所有情况。

注意

+1

这是非常普遍的,可以捕获您从/到YouTube获得的各种URL表单。 +1 – Bendoh 2013-02-15 18:21:12

+0

@Bendoh为什么这比所选答案w /'parse_str'更通用 - 这看起来好像能够完美捕捉URL中的每个变量? – Shackrock 2013-06-22 17:16:39

+1

所选答案将不会捕获/ v/或embed/表单的URL,只会将包含'v'的表单作为查询参数。它也不关注链接的主机名 - 它只是从查询字符串中带有'v'参数的任何URL中取出'v'的值。例如,http://www.youtube.com/v/ihCbVT637aM将无法正确解析。 – Bendoh 2013-06-27 20:08:38

2

你可以只使用parse_urlparse_str

$query_string = parse_url($url, PHP_URL_QUERY); 
parse_str($query_string); 
echo $v; 
0

另一个简单的方法是使用parse_str()

<?php 
    $url = 'http://www.youtube.com/watch?v=8GqqjVXhfMU&feature=youtube_gdata_player'; 
    parse_str($url, $yt); 

    // The associative array $yt now contains all of the key-value pairs from the querystring (along with the base 'watch' URL, but doesn't seem you need that) 
    echo $yt['v']; // echos '8GqqjVXhfMU'; 
?> 
+0

看起来像首先缺少parse_url,正如其他答案所述。用parse_url它可以工作。 FYI – Shackrock 2012-03-07 02:42:58

+0

[ORIG:没有必要parse_url。有人可能会说它更干净,但是 - 至少在PHP 5.3.6中 - 查询字符串参数前面的URL只是数组中的一个键。] - 编辑:啊,当这个参数只有一个QS时,功能必须拆分&。 parse_url将是更正确的方法。 – Morgon 2012-03-07 02:45:53

9

代替正则表达式的。我hightly建议​​和parse_str()

$url = "http://www.youtube.com/watch?v=8GqqjVXhfMU&feature=youtube_gdata_player"; 
parse_str(parse_url($url, PHP_URL_QUERY), $vars); 
echo $vars['v'];  

完成

+0

完美。谢谢。 – Shackrock 2012-03-07 02:43:35

+2

这不适用于https://www.youtube.com/v/qfx6yf8pux4 – 2014-10-01 19:41:39

0

的parse_url建议是很好的。如果你真的想要一个正则表达式,你可以使用这个:

/(?<=v=)[^&]+/` 
0

我已经使用了下面的模式,因为YouTube有太多一youtube-nocookie.com域的视频在年底$值= ID:

'@youtube(?:-nocookie)?\.com/watch[#\?].*?v=([^"\& ]+)@i', 
'@youtube(?:-nocookie)?\.com/embed/([^"\&\? ]+)@i', 
'@youtube(?:-nocookie)?\.com/v/([^"\&\? ]+)@i', 
'@youtube(?:-nocookie)?\.com/\?v=([^"\& ]+)@i', 
'@youtu\.be/([^"\&\? ]+)@i', 
'@gdata\.youtube\.com/feeds/api/videos/([^"\&\? ]+)@i', 

在你的情况下,将不仅意味着为常规YouTube.com URL扩展与可选(-nocookie)现有的表情就像这样:

if (preg_match('/youtube(?:-nocookie)\.com\/watch\?v=([^\&\?\/]+)/', $url, $id)) { 

如果你改变你的建议表达不含最终$,它应该像你打算的那样工作。我还添加了-nocookie。

/** 
* get YouTube video ID from URL 
* 
* @param string $url 
* @return string YouTube video id or FALSE if none found. 
*/ 
function youtube_id_from_url($url) { 
    $pattern = 
     '%^# Match any YouTube URL 
     (?:https?://)? # Optional scheme. Either http or https 
     (?:www\.)?  # Optional www subdomain 
     (?:    # Group host alternatives 
      youtu\.be/ # Either youtu.be, 
     |youtube(?:-nocookie)?\.com # or youtube.com and youtube-nocookie 
      (?:   # Group path alternatives 
      /embed/  # Either /embed/ 
      | /v/   # or /v/ 
      | /watch\?v= # or /watch\?v= 
     )    # End path alternatives. 
     )    # End host alternatives. 
     ([\w-]{10,12}) # Allow 10-12 for 11 char YouTube id. 
     %x' 
     ; 
    $result = preg_match($pattern, $url, $matches); 
    if (false !== $result) { 
     return $matches[1]; 
    } 
    return false; 
} 
0

解决方案,任何YouTube链接:

http://youtube.com/v/dQw4w9WgXcQ 
http://youtube.com/watch?v=dQw4w9WgXcQ 
http://www.youtube.com/watch?feature=player&v=dQw4w9WgXcQ&var2=bla 
http://youtu.be/dQw4w9WgXcQ 

==

https://stackoverflow.com/a/20614061/2165415

0

这里是一个解决方案

/** 
* credits goes to: http://stackoverflow.com/questions/11438544/php-regex-for-youtube-video-id 
* update: mobile link detection 
*/ 
public function parseYouTubeUrl($url) 
{ 
    $pattern = '#^(?:https?://)?(?:www\.)?(?:m\.)?(?:youtu\.be/|youtube\.com(?:/embed/|/v/|/watch\?v=|/watch\?.+&v=))([\w-]{11})(?:.+)?$#x'; 
    preg_match($pattern, $url, $matches); 
    return (isset($matches[1])) ? $matches[1] : false; 
} 

它能够处理移动链接了。

-1

这是我的检索Youtube ID的功能!

function getYouTubeId($url) { 
    if (!(strpos($url, 'v=') !== false)) return false; 
    $parse = explode('v=', $url); 
    $code = $parse[1]; 
    if (strlen($code) < 11) return false; 
    $code = substr($code, 0, 11); 
    return $code; 
} 
相关问题