php 使用 preg_match 解析 youtube 视频 ID
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/2936467/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
parse youtube video id using preg_match
提问by J.C
I am attempting to parse the video ID of a youtube URL using preg_match. I found a regular expression on this site that appears to work;
我正在尝试使用 preg_match 解析 youtube URL 的视频 ID。我在这个网站上发现了一个似乎有效的正则表达式;
(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]/)[^&\n]+|(?<=v=)[^&\n]+
As shown in this pic:
如这张图片所示:


My PHP is as follows, but it doesn't work (gives Unknown modifier '[' error)...
我的 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>";
?>
Cheers
干杯
回答by Benjam
This regex grabs the ID from all of the various URLs I could find... There may be more out there, but I couldn't find reference of them anywhere. If you come across one this doesn't match, please leave a comment with the URL, and I'll try and update the regex to match your URL.
这个正则表达式从我能找到的所有各种 URL 中获取 ID......那里可能还有更多,但我无法在任何地方找到它们的引用。如果您遇到不匹配的内容,请在 URL 上发表评论,我会尝试更新正则表达式以匹配您的 URL。
if (preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/\s]{11})%i', $url, $match)) {
    $video_id = $match[1];
}
Here is a sample of the URLs this regex matches: (there can be more content after the given URL that will be ignored)
以下是此正则表达式匹配的 URL 示例:(在给定 URL 之后可以有更多内容将被忽略)
- 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...
- 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.
它也适用于具有上述相同选项的 youtube-nocookie.com URL。
It will also pull the ID from the URL in an embed code (both iframe and object tags)
它还将从嵌入代码(iframe 和对象标签)中的 URL 中提取 ID
回答by Gumbo
回答by eyecatchUp
I had to deal with this for a PHP class i wrote a few weeks ago and ended up with a regex that matches any kind of strings: With or without URL scheme, with or without subdomain, youtube.com URL strings, youtu.be URL strings and dealing with all kind of parameter sorting. You can check it out at GitHubor simply copy and paste the code block below:
我不得不为几周前写的 PHP 类处理这个问题,最终得到一个匹配任何类型字符串的正则表达式:有或没有 URL 方案,有或没有子域,youtube.com URL 字符串,youtu.be URL字符串并处理各种参数排序。你可以在 GitHub 上查看,或者简单地复制并粘贴下面的代码块:
/**
 *  Check if input string is a valid YouTube URL
 *  and try to extract the YouTube Video ID from it.
 *  @author  Stephan Schmitz <[email protected]>
 *  @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;
}
To explain the regex, here's a spilt up version:
为了解释正则表达式,这里有一个溢出的版本:
/**
 *  Check if input string is a valid YouTube URL
 *  and try to extract the YouTube Video ID from it.
 *  @author  Stephan Schmitz <[email protected]>
 *  @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;
}
回答by Modder
I perfected regex from the leader answer. It also grabs the ID from all of the various URLs, but more correctly.
我从领导者的回答中完善了正则表达式。它还从所有不同的 URL 中获取 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];
}
Also, it correctly handles the wrong IDs, which more than 11 characters.
此外,它可以正确处理超过 11 个字符的错误 ID。
http://www.youtube.com/watch?v=0zM3nApSvMgDw3qlxF
http://www.youtube.com/watch?v=0zM3nApSvMgDw3qlxF
回答by Dogbert
Use
用
 preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]/)[^&\n]+|(?<=v=)[^&\n]+#", $subject, $matches);
回答by Fixer
Parse Start parameter for BBcode (https://developers.google.com/youtube/player_parameters#start)
解析 BBcode 的开始参数 ( https://developers.google.com/youtube/player_parameters#start)
example: [yt]http://www.youtube.com/watch?v=G059ou-7wmo#t=58[/yt]
例子: [yt]http://www.youtube.com/watch?v=G059ou-7wmo#t=58[/yt]
PHP regex:
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'
replace:
代替:
'<iframe id="ytplayer" type="text/html" width="639" height="360" src="http://www.youtube.com/embed/?rel=0&vq=hd1080&start=" frameborder="0" allowfullscreen></iframe>'
回答by m4olivei
I didn't see anyone directly address the PHP error, so I'll try to explain.
我没有看到有人直接解决 PHP 错误,所以我会试着解释一下。
The reason for the "Unknown modifier '['" error is that you forgot to wrap your regex in delimiters. PHP just takes the first character as a delimiter, so long as it's a non-alphanumeric, non-whitespace ASCII character. So in your regex:
“未知修饰符'['”错误的原因是您忘记将正则表达式包装在分隔符中。PHP 仅将第一个字符作为分隔符,只要它是非字母数字、非空白 ASCII 字符即可。所以在你的正则表达式中:
preg_match("(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]/)[^&\n]+|(?<=v=)[^&\n]+", $subject, $matches);
PHP thinks you meant (as an opening delimiter.  It then finds what it thinks is your closing delimiter, the next )and assumes what follows are pattern modifiers.  However it finds that your first pattern modifier, the next character after the first ), is [.  [is obviously not a valid pattern modifier, which is why you get the error that you do.
PHP 认为您的意思是(作为开始分隔符。然后它会找到它认为是您的结束定界符,下一个)并假设接下来是模式修饰符。但是它发现您的第一个模式修饰符,第一个之后的下一个字符)是[.  [显然不是一个有效的模式修饰符,这就是为什么你会得到你所做的错误。
The solution is to simply wrap your regex in delimiters and make sure any delimiters within the regex that you want to match literally are escaped.  I like to use ~as delimiters, b/c you rarely need to match a literal ~in a regex.
解决方案是简单地将您的正则表达式包装在分隔符中,并确保您想要逐字匹配的正则表达式中的任何分隔符都被转义。我喜欢~用作分隔符,b/c 你很少需要匹配~正则表达式中的文字。
回答by Novan Adrian
You forgot to escape the slash character. So this one should do the job:
您忘记转义斜杠字符。所以这个应该做的工作:
preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]\/)[^&\n]+|(?<=v=)[^&\n]+#", $subject, $matches);
回答by T.Todua
this worked for me.
这对我有用。
$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));
回答by diEcho
use below code
使用下面的代码
$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]);
}

