Regex, чтобы соответствовать URL-адресам YouTube - PullRequest
0 голосов
/ 17 сентября 2010

Я пытаюсь проверить URL-адрес 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 ]

3 голосов
/ 17 сентября 2010

Чтобы предоставить альтернативу, которая является более крупной и менее элегантной, чем регулярное выражение, но работает с собственными функциями синтаксического анализа URL в 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
0 голосов
/ 06 июня 2014

Следующее регулярное выражение будет соответствовать любой ссылке на YouTube:

$pattern='@(((http(s)?://(www\.)?)|(www\.)|\s)(youtu\.be|youtube\.com)/(embed/|v/|watch(\?v=|\?.+&v=|/))?([a-zA-Z0-9._\/~#&=;%+?-\!]+))@si';
0 голосов
/ 27 июля 2013

Блок «v = ...» не обязательно является первым параметром в части запроса URL-адреса. Я бы рекомендовал использовать PHP функцию parse_url (), чтобы разбить 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;
}
0 голосов
/ 17 сентября 2010

Краткий ответ:

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

Здесь сделано несколько предположений, поэтому позвольте мне объяснить:

  • Я добавил группу захвата ( ... ) вокруг всей <a href="http://www.youtube.com/watch?v=blah" rel="nofollow noreferrer">http://www.youtube.com/watch?v=blah</a> части ссылки, так что мы можем сказать: «Я хочу получить всю проверенную ссылку до и включая? 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 голосов
/ 17 сентября 2010

Проблема в том, что вам не требуется какое-то определенное количество символов в части v = URL. Так, например, проверка

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...