Мне пришлось иметь дело с этим для класса PHP, который я написал несколько недель назад, и в результате я получил регулярное выражение, которое соответствует любому виду строк: с или без схемы URL, с или без субдомена, строки URL-адреса youtube.com, youtu.be URL строки и работа со всеми видами сортировки параметров.Вы можете проверить это на GitHub или просто скопировать и вставить следующий блок кода:
/**
* Check if input string is a valid YouTube URL
* and try to extract the YouTube Video ID from it.
* @author Stephan Schmitz <eyecatchup@gmail.com>
* @param $url string The string that shall be checked.
* @return mixed Returns YouTube Video ID, or (boolean) false.
*/
function parse_yturl($url)
{
$pattern = '#^(?:https?://|//)?(?:www\.|m\.)?(?:youtu\.be/|youtube\.com/(?:embed/|v/|watch\?v=|watch\?.+&v=))([\w-]{11})(?![\w-])#';
preg_match($pattern, $url, $matches);
return (isset($matches[1])) ? $matches[1] : false;
}
Контрольные примеры: https://3v4l.org/GEDT0
Версия JavaScript: https://stackoverflow.com/a/10315969/624466
Чтобы объяснить регулярное выражение, вот разделенная версия:
/**
* Check if input string is a valid YouTube URL
* and try to extract the YouTube Video ID from it.
* @author Stephan Schmitz <eyecatchup@gmail.com>
* @param $url string The string that shall be checked.
* @return mixed Returns YouTube Video ID, or (boolean) false.
*/
function parse_yturl($url)
{
$pattern = '#^(?:https?://|//)?' # Optional URL scheme. Either http, or https, or protocol-relative.
. '(?:www\.|m\.)?' # Optional www or m subdomain.
. '(?:' # Group host alternatives:
. 'youtu\.be/' # Either youtu.be,
. '|youtube\.com/' # or youtube.com
. '(?:' # Group path alternatives:
. 'embed/' # Either /embed/,
. '|v/' # or /v/,
. '|watch\?v=' # or /watch?v=,
. '|watch\?.+&v=' # or /watch?other_param&v=
. ')' # End path alternatives.
. ')' # End host alternatives.
. '([\w-]{11})' # 11 characters (Length of Youtube video ids).
. '(?![\w-])#'; # Rejects if overlong id.
preg_match($pattern, $url, $matches);
return (isset($matches[1])) ? $matches[1] : false;
}