Проверка URL-адреса Youtube с помощью регулярного выражения
Я пытаюсь проверить URL-адреса 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";
}
Я хочу проверить следующие варианты URL-адресов Youtube:
- С и без http://
- С www и без него.
- С URL-адресами youtube.com и youtu.be
- Должен иметь/смотреть?v=
- Должна иметь уникальную строку видео (в приведенном выше примере "VPFZJCCZDTCK")
Однако я не думаю, что у меня есть своя логика правильно, потому что по какой-то причине он возвращает true для: www.youtube.co/watch?v=vpfzjcCzdtCk
(Обратите внимание, что я написал это неправильно с .co
и не .com
)
5 answers
В этом вашем регулярном выражении много избыточностей (а также синдром наклоняющейся зубочистки). Это, однако, должно привести к результатам:
$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
)
Проверка доменного имени и извлечение идентификатора видео оставлены в качестве упражнения для читателя.
Я поддался войне комментариев ниже; благодаря Тони Ориолу регулярное выражение теперь работает на коротких (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";
}
У вас был ||, что в любом случае нормально без ^$.
Это должно сделать это:
$valid = preg_match("/^(https?\:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/watch\?v\=\w+$/", $youtube_url);
if ($valid) {
echo "Valid";
} else {
echo "Invalid";
}
Я полагаюсь на другие ответы на этой странице для анализа синтаксиса URL, но для самих значений идентификатора YouTube вы можете быть немного более конкретными, как я описываю в следующем ответе на StackExchange/webapps:
Формат для идентификатора видео на YouTube - https://webapps.stackexchange.com/a/101153/141734
Идентификатор видео
Для видеоизображения это 8-байтовый (64-разрядный) целое число. Для применения кодировки Base64 к 8 байтам данных требуется 11 символов. Однако, поскольку каждый символ Base64 содержит ровно 6 бит, это распределение может фактически содержать до
11 × 6 = 66
бит - избыток в 2 бита по сравнению с тем, что требуется нашей полезной нагрузке. Избыточные биты равны нулю, что приводит к исключению появления определенных символов в последней позиции кодированной строки. В частности, Видеоид всегда будет заканчиваться одним из следующих:{ A, E, I, M, Q, U, Y, c, g, k, o, s, w, 0, 4, 8 }
Таким образом, регулярное выражение (регулярное выражение) для видеоизображения будет выглядеть следующим образом:
[-_A-Za-z0-9]{10}[AEIMQUYcgkosw048]
Идентификатор канала или списка воспроизведения
Строки Идентификатора канала и списка воспроизведения создаются с помощью Base64-кодирования 128-битного (16-байтового) двоичного целого числа. Опять же, здесь расчет на Base64 правильно предсказывает наблюдаемую длину строки из 22 символов. В этом случае выходные данные способны кодировать
22 × 6 = 132
бит, избыток в 4 бита; эти нули заканчиваются ограничение большинства из 64 символов алфавита от появления в последней позиции, и только 4 остаются подходящими. Все строки идентификатора канала заканчиваются одним из следующих:{ A, Q, g, w }
Это дает нам регулярное выражение для идентификатора канала :
[-_A-Za-z0-9]{21}[AQgw]