Я пытаюсь проверить URL Youtube с помощью regex:
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-]
. Любая помощь приветствуется, спасибо.
Проблема в том, что вам не требуется определенное количество символов в v = части URL. Так, например, проверка
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-].
Чтобы предоставить альтернативу, которая больше и гораздо менее элегантна, чем регулярное выражение, но работает с функциями PHP для парного разбора PHP, поэтому в долгосрочной перспективе это может быть немного более надежным:
$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
Короткий ответ:
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
«V = …» blob не гарантированно будет первым параметром в части запроса URL-адреса. Я бы рекомендовал использовать функцию parse_url () PHP, чтобы разбить 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; }
Следующее regex будет соответствовать любой ссылке youtube:
$pattern='@(((http(s)?://(www\.)?)|(www\.)|\s)(youtu\.be|youtube\.com)/(embed/|v/|watch(\?v=|\?.+&v=|/))?([a-zA-Z0-9._\/~#&=;%+?-\!]+))@si';