正则表达式匹配Youtube网址

时间:2010-09-17 17:40:39

标签: php regex youtube

我正在尝试使用正则表达式验证Youtube网址:

preg_match('~http://youtube.com/watch\?v=[a-zA-Z0-9-]+~', $videoLink)

它有点工作,但它可以匹配格式错误的URL。例如,这将匹配ok:

http://www.youtube.com/watch?v=Zu4WXiPRek

但是这样:

http://www.youtube.com/watch?v=Zu4WX£&P!ek

这不会:

http://www.youtube.com/watch?v=!Zu4WX£&P4ek

我认为这是因为+运算符。它与v=之后的第一个字符相匹配,当它需要尝试匹配v=后面的所有内容与[a-zA-Z0-9-]时。感谢任何帮助。谢谢。

5 个答案:

答案 0 :(得分:3)

提供比正则表达式更大且更不优雅的替代方案,但与PHP的本机URL解析函数一起使用,因此从长远来看它可能更可靠:

 $url = "http://www.youtube.com/watch?v=Zu4WXiPRek";

 $query_string = parse_url($url, PHP_URL_QUERY); // v=Zu4WXiPRek

 $query_string_parsed = array();                        
 parse_str($query_string, $query_string_parsed); // an array with all GET params

 echo($query_string_parsed["v"]); // Will output Zu4WXiPRek that you can then
                                  // validate for [a-zA-Z0-9] using a regex

答案 1 :(得分:0)

问题是您不需要在URL的v =部分中使用任何特定数量的字符。所以,例如,检查

http://www.youtube.com/watch?v=Zu4WX£&P!ek

将匹配

http://www.youtube.com/watch?v=Zu4WX

因此返回true。您需要在v = part中指定所需的字符数:

preg_match('~http://youtube.com/watch\?v=[a-zA-Z0-9-]{10}~', $videoLink)

或指定组[a-zA-Z0-9-]必须是字符串的最后一部分:

preg_match('~http://youtube.com/watch\?v=[a-zA-Z0-9-]+$~', $videoLink)

你的另一个例子

http://www.youtube.com/watch?v=!Zu4WX£&P4ek

不匹配,因为+符号要求至少一个字符必须与[a-zA-Z0-9 - ]匹配。

答案 2 :(得分:0)

简短回答:

preg_match('%(http://www.youtube.com/watch\?v=(?:[a-zA-Z0-9-])+)(?:[&"\'\s])%', $videoLink)

这里有一些假设,让我解释一下:

  • 我在链接的整个( ... )部分添加了一个捕获组http://www.youtube.com/watch?v=blah,以便我们可以说“我希望获得整个经过验证的链接,包括?v = movieHash”< / LI>
  • 我在您的字符集(?: ... )周围添加了非捕获组[a-zA-Z0-9-],并在其外部留下了+号。这将允许我们将所有允许的字符匹配到某个点。
  • 最重要的是,您需要告诉它您期望您的链接是如何终止的。我用(?:[&"\'\s])

    猜你

    ?)是否采用html格式(例如锚标签)?如果是这样, href 中的链接显然会以'结束。
    ?)或者查询字符串可能还有更多内容,因此在 v 的值之后会有&amp;
    ?)链接结束后可能有空格或换行符 \ s

重要的一点是,如果您知道正在搜索的内容,那么您可以获得更准确的结果,就像许多正则表达式一样。

这个非捕获组(我正在为你做出假设)会在你关心的事情之后找到并忽略所有额外的垃圾(?​​v = awesomeMovieHash)

结果:

http://www.youtube.com/watch?v=Zu4WXiPRek
 - Group 1 contains the http://www.youtube.com/watch?v=Zu4WXiPRek

http://www.youtube.com/watch?v=Zu4WX&a=b
 - Group 1 contains http://www.youtube.com/watch?v=Zu4WX

http://www.youtube.com/watch?v=!Zu4WX£&P4ek
 - No match

a href="http://www.youtube.com/watch?v=Zu4WX&size=large"
 - Group 1 contains http://www.youtube.com/watch?v=Zu4WX

http://www.youtube.com/watch?v=Zu4WX£&P!ek
 - No match

答案 3 :(得分:0)

“v = ...”blob不能保证是URL查询部分的第一个参数。我建议使用PHP的parse_url()函数将URL分解为其组成部分。如果有人以“https://”开头,或者只是使用“youtube.com”代替“www.youtube.com”等,您也可以重新组合原始网址。

function get_youtube_vidid ($url) {
    $vidid = false;
    $valid_schemes = array ('http', 'https');
    $valid_hosts = array ('www.youtube.com', 'youtube.com');
    $valid_paths = array ('/watch');

    $bits = parse_url ($url);
    if (! is_array ($bits)) {
        return false;
    }
    if (! (array_key_exists ('scheme', $bits)
            and array_key_exists ('host', $bits)
            and array_key_exists ('path', $bits)
            and array_key_exists ('query', $bits))) {
        return false;
    }
    if (! in_array ($bits['scheme'], $valid_schemes)) {
        return false;
    }
    if (! in_array ($bits['host'], $valid_hosts)) {
        return false;
    }
    if (! in_array ($bits['path'], $valid_paths)) {
        return false;
    }
    $querypairs = explode ('&', $bits['query']);
    if (count ($querypairs) < 1) {
        return false;
    }
    foreach ($querypairs as $querypair) {
        list ($key, $value) = explode ('=', $querypair);
        if ($key == 'v') {
            if (preg_match ('/^[a-zA-Z0-9\-_]+$/', $value)) {
                # Set the return value
                $vidid = $value;
            }
        }
    }

    return $vidid;
}

答案 4 :(得分:0)

以下正则表达式将匹配任何youtube链接:

$pattern='@(((http(s)?://(www\.)?)|(www\.)|\s)(youtu\.be|youtube\.com)/(embed/|v/|watch(\?v=|\?.+&v=|/))?([a-zA-Z0-9._\/~#&=;%+?-\!]+))@si';