匹配 Youtube URL 的正则表达式

问题描述 投票:0回答:6

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

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

它确实有效,但它可以匹配格式错误的 URL。例如,这样就可以匹配:

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-]
之后的第一个字符。感谢任何帮助,谢谢。

php regex youtube
6个回答
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

0
投票

问题是您不需要 URL 的 v= 部分包含任何特定数量的字符。例如,检查

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

将匹配

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

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

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-]。


0
投票

简短回答:

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

这里做了一些假设,所以让我解释一下:

  • 我在链接的整个
    ( ... )
    部分添加了一个捕获组
    http://www.youtube.com/watch?v=blah
    ,这样我们就可以说“我想要获取整个经过验证的链接,包括 ?v=movieHash”
  • 我在你的字符集
    (?: ... )
    周围添加了非捕获组
    [a-zA-Z0-9-]
    ,并将+号留在了外面。这将使我们能够在一定程度上匹配所有允许的字符。
  • 最重要的是,您需要告诉它您期望您的链接如何终止。我来帮你猜猜

    (?:[&"\'\s])

    ?)它会是 html 格式(例如锚标记)吗?如果是这样,href中的链接显然将以'结束。
    ?)或者查询字符串可能还有更多内容,因此在 v 的值后面会有一个 &
    ?)链接末尾后可能有空格或换行符\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

0
投票

“v=...” blob 不保证是 URL 查询部分中的第一个参数。我建议使用 PHP 的 parse_url() 函数将 URL 分解为其组成部分。如果有人以“https://”开头字符串或简单地使用“youtube.com”而不是“www.youtube.com”等,您还可以重新组装原始 URL。

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

0
投票

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

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

0
投票
^(?:(?:https?:)?\/\/)?(?:(?:(?:www|m(?:usic)?)\.)?youtu(?:\.be|be(?:-nocookie)?\.com))\/(?:shorts\/|live\/|v\/|embed\/|watch(?:\/|\?(?:\S+=\S+&)*v=)|oembed\?url=https?%3A\/\/(?:www|m(?:usic)?)\.youtube(?:-nocookie)?\.com\/watch\?(?:\S+=\S+&)*v%3D|attribution_link\?(?:\S+=\S+&)*u=(?:\/|%2F)watch(?:\?|%3F)v(?:=|%3D)|playlist\?(?:\S+=\S+&)*list=)?([\w-]+)[\?&#]?\S*$

从任何已知的 YouTube URL(还有音乐、短片、现场、嵌入、nocookie 等)中提取视频 ID。这是相关问题下的答案https://stackoverflow.com/a/78172756/11194000

如果您愿意,可以在正则表达式中使用

{11}
而不是
+
将视频 ID 限制为 11 个字符。

© www.soinside.com 2019 - 2024. All rights reserved.