使用preg_match解析youtube视频ID

时间:2010-05-29 20:19:42

标签: php regex parsing youtube

我正在尝试使用preg_match解析youtube网址的视频ID。我发现这个网站上的正则表达似乎有用;

(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]/)[^&\n]+|(?<=v=)[^&\n]+

如图所示:

alt text

我的PHP如下,但它不起作用(给出未知修饰符'['错误)......

<?
 $subject = "http://www.youtube.com/watch?v=z_AbfPXTKms&NR=1";

 preg_match("(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]/)[^&\n]+|(?<=v=)[^&\n]+", $subject, $matches);

 print "<pre>";
 print_r($matches);
 print "</pre>";

?>

干杯

10 个答案:

答案 0 :(得分:222)

这个正则表达式从我能找到的所有各种URL中获取ID ... 可能还有更多,但我无法在任何地方找到它们的参考。如果您遇到与此匹配不匹配的内容,请在网址上留言,我会尝试更新正则表达式以匹配您的网址。

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

以下是此正则表达式匹配的网址示例:(在给定的网址之后可能会有更多内容被忽略)

它也适用于具有相同选项的youtube-nocookie.com网址。

它还会从嵌入代码(iframe和object标签)中的URL中提取ID

答案 1 :(得分:11)

最好使用parse_urlparse_str来解析网址和查询字符串:

$subject = "http://www.youtube.com/watch?v=z_AbfPXTKms&NR=1";
$url = parse_url($subject);
parse_str($url['query'], $query);
var_dump($query);

答案 2 :(得分:7)

我必须为几周前编写的PHP类处理这个问题,并最终得到一个匹配任何类型字符串的正则表达式:有或没有URL方案,有或没有子域,youtube.com URL字符串,youtu .be URL字符串并处理所有类型的参数排序。您可以查看at GitHub或只是复制并粘贴下面的代码块:

/**
 *  Check if input string is a valid YouTube URL
 *  and try to extract the YouTube Video ID from it.
 *  @author  Stephan Schmitz <eyecatchup@gmail.com>
 *  @param   $url   string   The string that shall be checked.
 *  @return  mixed           Returns YouTube Video ID, or (boolean) false.
 */        
function parse_yturl($url) 
{
    $pattern = '#^(?:https?://)?(?:www\.)?(?: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;
}

要解释正则表达式,这是一个溢出的版本:

/**
 *  Check if input string is a valid YouTube URL
 *  and try to extract the YouTube Video ID from it.
 *  @author  Stephan Schmitz <eyecatchup@gmail.com>
 *  @param   $url   string   The string that shall be checked.
 *  @return  mixed           Returns YouTube Video ID, or (boolean) false.
 */        
function parse_yturl($url) 
{
    $pattern = '#^(?:https?://)?';    # Optional URL scheme. Either http or https.
    $pattern .= '(?:www\.)?';         #  Optional www subdomain.
    $pattern .= '(?:';                #  Group host alternatives:
    $pattern .=   'youtu\.be/';       #    Either youtu.be,
    $pattern .=   '|youtube\.com';    #    or youtube.com
    $pattern .=   '(?:';              #    Group path alternatives:
    $pattern .=     '/embed/';        #      Either /embed/,
    $pattern .=     '|/v/';           #      or /v/,
    $pattern .=     '|/watch\?v=';    #      or /watch?v=,    
    $pattern .=     '|/watch\?.+&v='; #      or /watch?other_param&v=
    $pattern .=   ')';                #    End path alternatives.
    $pattern .= ')';                  #  End host alternatives.
    $pattern .= '([\w-]{11})';        # 11 characters (Length of Youtube video ids).
    $pattern .= '(?:.+)?$#x';         # Optional other ending URL parameters.
    preg_match($pattern, $url, $matches);
    return (isset($matches[1])) ? $matches[1] : false;
}

答案 3 :(得分:5)

我从领导回答中完善了正则表达式。它还会从所有各种网址中获取ID,但更正确

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

此外,它正确处理错误的ID,超过11个字符。

http://www.youtube.com/watch?v=0zM3nApSvMgDw3qlxF

答案 4 :(得分:2)

使用

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

答案 5 :(得分:1)

你忘了逃避斜线角色。所以这个应该做的工作:

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

答案 6 :(得分:1)

BBcode的起始参数(https://developers.google.com/youtube/player_parameters#start

示例:[yt]http://www.youtube.com/watch?v=G059ou-7wmo#t=58[/yt]

PHP正则表达式:

'#\[yt\]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-]*(t=(\d+))?\[/yt\]#Uim'

<强>取代:

'<iframe id="ytplayer" type="text/html" width="639" height="360" src="http://www.youtube.com/embed/$1?rel=0&vq=hd1080&start=$3" frameborder="0" allowfullscreen></iframe>'

答案 7 :(得分:1)

我没有看到有人直接解决PHP错误,所以我会尝试解释。

“未知修饰符'['”错误的原因是您忘记将正则表达式包装在分隔符中。 PHP只是将第一个字符作为分隔符,只要它是非字母数字,非空白ASCII字符。所以在你的正则表达式中:

preg_match("(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]/)[^&\n]+|(?<=v=)[^&\n]+", $subject, $matches);

PHP认为您将(视为开头分隔符。然后它会找到它认为是你的结束分隔符,下一个)并假设下面是模式修饰符。但是,它会发现您的第一个模式修饰符(第一个)之后的下一个字符)是[[显然不是一个有效的模式修饰符,这就是你得到错误的原因。

解决方案是简单地将正则表达式包装在分隔符中,并确保正则表达式中要匹配的正则表达式中的任何分隔符都被转义。我喜欢使用~作为分隔符,b / c您很少需要匹配正则表达式中的文字~

答案 8 :(得分:0)

使用下面的代码

$url = "" // here is url of youtube video
$pattern = getPatternFromUrl($url); //this will retun video id

function getPatternFromUrl($url)
{
$url = $url.'&';
$pattern = '/v=(.+?)&+/';
preg_match($pattern, $url, $matches);
//echo $matches[1]; die;
return ($matches[1]);
}

答案 9 :(得分:0)

这对我有用。

$yout_url='http://www.youtube.com/watch?v=yxYjeNZvICk&blabla=blabla';

$videoid = preg_replace("#[&\?].+$#", "", preg_replace("#http://(?:www\.)?youtu\.?be(?:\.com)?/(embed/|watch\?v=|\?v=|v/|e/|.+/|watch.*v=|)#i", "", $yout_url));