我正在尝试验证我的应用程序的 YouTube 网址。
到目前为止我有以下内容:
// Set the youtube URL
$youtube_url = "www.youtube.com/watch?v=vpfzjcCzdtCk";
if (preg_match("/((http\:\/\/){0,}(www\.){0,}(youtube\.com){1} || (youtu\.be){1}(\/watch\?v\=[^\s]){1})/", $youtube_url) == 1)
{
echo "Valid";
else
{
echo "Invalid";
}
我希望验证 Youtube 网址的以下变体:
但是,我认为我的逻辑不正确,因为由于某种原因,它返回 true 为:
www.youtube.co/watch?v=vpfzjcCzdtCk
(请注意,我用 .co
而不是 .com
写错了)
你的这个正则表达式中有很多冗余(还有,倾斜牙签综合症)。不过,这应该会产生结果:
$rx = '~
^(?:https?://)? # Optional protocol
(?:www[.])? # Optional sub-domain
(?:youtube[.]com/watch[?]v=|youtu[.]be/) # Mandatory domain name (w/ query string in .com)
([^&]{11}) # Video id of 11 characters as capture group 1
~x';
$has_match = preg_match($rx, $url, $matches);
// if matching succeeded, $matches[1] would contain the video ID
一些注意事项:
~
作为分隔符,以避免 LTS[.]
代替 \.
来提高视觉易读性并避免 LTS。 (“特殊”字符 - 例如点 .
- 对字符类(方括号内)没有影响)x
修饰符(它具有进一步的含义;请参阅有关模式修饰符的文档),它还允许在正则表达式中添加注释(?: <pattern> )
。这使得表达更加高效。可选地,要从(或多或少完整的)URL 中提取值,您可能需要使用
parse_url()
:
$url = 'http://youtube.com/watch?v=VIDEOID';
$parts = parse_url($url);
print_r($parts);
输出:
Array
(
[scheme] => http
[host] => youtube.com
[path] => /watch
[query] => v=VIDEOID
)
验证域名并提取视频 ID 留给读者作为练习。
我屈服于下面的评论战;感谢 Toni Oriol,正则表达式现在也适用于短 (youtu.be) URL。
parse_url()
。
$parts = parse_url($url);
if ($parts['host'] == 'youtube.com' && ...) {
// your code
}
虽然代码更多,但更具可读性,因此更易于维护。
请尝试:
// Set the youtube URL
$youtube_url = "www.youtube.com/watch?v=vpfzjcCzdtCk";
if (preg_match("/^((http\:\/\/){0,}(www\.){0,}(youtube\.com){1}|(youtu\.be){1}(\/watch\?v\=[^\s]){1})$/", $youtube_url) == 1)
{
echo "Valid";
}
else
{
echo "Invalid";
}
你有||无论如何,没有 ^$ 也没关系。
我遵循本页上的其他答案来解析 URL 语法,但对于 YouTube ID 值本身,您可以更具体一点,正如我在 StackExchange/WebApps 上的以下答案中所述:
YouTube 视频 ID 格式 - https://webapps.stackexchange.com/a/101153/141734
视频ID
对于videoId,它是一个8字节(64位)整数。对 8 字节数据应用 Base64 编码需要 11 个字符。然而,由于每个 Base64 字符恰好传送 6 位,因此该分配实际上最多可以容纳
位,比我们的有效负载所需的多出 2 位。多余的位设置为零,其效果是排除某些字符出现在编码字符串的最后位置。特别是,videoId始终以以下之一结尾:11 × 6 = 66
{ A, E, I, M, Q, U, Y, c, g, k, o, s, w, 0, 4, 8 }
因此,videoId的正则表达式 (RegEx) 将如下所示:
[-_A-Za-z0-9]{10}[AEIMQUYcgkosw048]
频道或播放列表 ID
channelId 和playlistId 字符串是通过 Base64 编码 128 位(16 字节)二进制整数生成的。同样,根据 Base64 进行的计算正确预测了观察到的22 个字符 的字符串长度。在这种情况下,输出能够编码
位,剩余 4 位;这些零最终限制了 64 个字母符号中的大部分出现在最后一个位置,只有 4 个仍然符合条件。所有 channelId 字符串均以以下之一结尾:22 × 6 = 132
{ A, Q, g, w }
这为我们提供了 channelId:
的正则表达式[-_A-Za-z0-9]{21}[AQgw]
这应该可以做到:
$valid = preg_match("/^(https?\:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/watch\?v\=\w+$/", $youtube_url);
if ($valid) {
echo "Valid";
} else {
echo "Invalid";
}
如果您想涵盖所有变体,请查看:
^(?:(?:https?:)?\/\/)?(?:(?:(?:www|m(?:usic)?)\.)?youtu(?:\.be|be(?:-nocookie)?\.com))\/(?:shorts\/|live\/|v\/|e(?:mbed)?\/|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(还有 music.*、shorts/、live/、e/ embed/、v/、*-nocookie 等)中提取视频 ID。
如果需要,您可以在正则表达式中使用
{11}
而不是 +
将视频 ID 限制为 11 个字符。或者用格伦的回答。