Улучшение регулярного выражения для разбора URL-адресов YouTube/Vimeo
Я создал функцию (в JavaScript), которая получает URL-адрес от YouTube или Vimeo. Он определяет провайдера и идентификатор для этого конкретного видео (демо: http://jsfiddle.net/csjwf/).
function parseVideoURL(url) {
var provider = url.match(/http:\/\/(:?www.)?(\w*)/)[2],
id;
if(provider == "youtube") {
id = url.match(/http:\/\/(?:www.)?(\w*).com\/.*v=(\w*)/)[2];
} else if (provider == "vimeo") {
id = url.match(/http:\/\/(?:www.)?(\w*).com\/(\d*)/)[2];
} else {
throw new Error("parseVideoURL() takes a YouTube or Vimeo URL");
}
return {
provider : provider,
id : id
}
}
Он работает, однако, как новичок в регулярном выражении, я ищу способы его улучшить. Вход, с которым я имею дело, обычно выглядит так:
http://vimeo.com/(id)
http://youtube.com/watch?v=(id)&blahblahblah.....
1) Сейчас я делаю три отдельных матча, было бы целесообразно попробовать все сделать в одном выражении? Если да, то как?
2) Могут ли существующие совпадения быть более краткими? Являются ли они излишне сложными? или, возможно, недостаточно?
3) Есть ли какой-либо URL-адрес YouTube или Vimeo, который не может быть проанализирован? Я пробовал довольно много, и пока это работает очень хорошо.
Подводя итог: Я просто ищу способы улучшить вышеупомянутую функцию. Любые советы приветствуются.
Ответы
Ответ 1
Я не уверен в вашем вопросе 3), но при условии, что ваша индукция по формам url верна, регулярные выражения можно объединить в один:
/http:\/\/(?:www.)?(?:(vimeo).com\/(.*)|(youtube).com\/watch\?v=(.*?)&)/
Вы получите матч под разными позициями (1-й и 2-й матчи, если vimeo, 3-й и 4-й матчи, если youtube), поэтому вам просто нужно это обработать.
Или, если вы абсолютно уверены, что идентификатор vimeo включает только числа, вы можете сделать:
/http:\/\/(?:www.)?(vimeo|youtube).com\/(?:watch\?v=)?(.*?)(?:\z|&)/
а провайдер и идентификатор будут отображаться в соответствии с 1-м и 2-м совпадениями соответственно.
Ответ 2
Здесь моя попытка регулярного выражения, которая охватывает наиболее распространенные случаи:
function parseVideo(url) {
// - Supported YouTube URL formats:
// - http://www.youtube.com/watch?v=My2FRPA3Gf8
// - http://youtu.be/My2FRPA3Gf8
// - https://youtube.googleapis.com/v/My2FRPA3Gf8
// - Supported Vimeo URL formats:
// - http://vimeo.com/25451551
// - http://player.vimeo.com/video/25451551
// - Also supports relative URLs:
// - //player.vimeo.com/video/25451551
url.match(/(http:\/\/|https:\/\/|)(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);
var type = null;
if (RegExp.$3.indexOf('youtu') > -1) {
type = 'youtube';
} else if (RegExp.$3.indexOf('vimeo') > -1) {
type = 'vimeo';
}
return {
type: type,
id: RegExp.$6
};
}
Ответ 3
Regex отлично полон, но может быстро усложниться.
http://jsfiddle.net/8nagx2sk/
function parseYouTube(str) {
// link : //youtube.com/watch?v=Bo_deCOd1HU
// share : //youtu.be/Bo_deCOd1HU
// embed : //youtube.com/embed/Bo_deCOd1HU
var re = /\/\/(?:www\.)?youtu(?:\.be|be\.com)\/(?:watch\?v=|embed\/)?([a-z0-9_\-]+)/i;
var matches = re.exec(str);
return matches && matches[1];
}
function parseVimeo(str) {
// embed & link: http://vimeo.com/86164897
var re = /\/\/(?:www\.)?vimeo.com\/([0-9a-z\-_]+)/i;
var matches = re.exec(str);
return matches && matches[1];
}
Иногда простой код лучше других разработчиков.
https://jsfiddle.net/1dzb5ag1/
// protocol and www neutral
function getVideoId(url, prefixes) {
var cleaned = url.replace(/^(https?:)?\/\/(www\.)?/, '');
for(var i = 0; i < prefixes.length; i++) {
if (cleaned.indexOf(prefixes[i]) === 0)
return cleaned.substr(prefixes[i].length)
}
return undefined;
}
function getYouTubeId(url) {
return getVideoId(url, [
'youtube.com/watch?v=',
'youtu.be/',
'youtube.com/embed/',
'youtube.googleapis.com/v/'
]);
}
function getVimeoId(url) {
return getVideoId(url, [
'vimeo.com/',
'player.vimeo.com/'
]);
}
Что вы предпочитаете обновлять?
Ответ 4
Вот мое регулярное выражение
http://jsfiddle.net/csjwf/1/
Ответ 5
о пиле ответ:
небольшое обновление для второго регулярного выражения:
/http:\/\/(?:www\.)?(vimeo|youtube)\.com\/(?:watch\?v=)?(.*?)(?:\z|$|&)/
(экранирование точек предотвращает совпадение URL-адреса типа www_vimeo_com/... и $added...)
вот та же самая идея для сопоставления встроенных URL:
/http:\/\/(?:www\.|player\.)?(vimeo|youtube)\.com\/(?:embed\/|video\/)?(.*?)(?:\z|$|\?)/
Ответ 6
Для Vimeo не полагайтесь на Regex, поскольку Vimeo время от времени меняет/обновляет свой шаблон URL. По состоянию на 2 октября 2017 года Vimeo поддерживает шесть схем URL.
https://vimeo.com/*
https://vimeo.com/*/*/video/*
https://vimeo.com/album/*/video/*
https://vimeo.com/channels/*/*
https://vimeo.com/groups/*/videos/*
https://vimeo.com/ondemand/*/*
Вместо этого используйте их API для проверки URL-адресов vimeo. Вот этот oEmbed (doc) API, который берет URL, проверяет его действительность и возвращает объект с кучей видеоинформации (проверьте страницу dev). Хотя это и не предназначено, но мы можем легко использовать это, чтобы проверить, является ли данный URL от Vimeo или нет.
Итак, с AJAX это будет выглядеть так,
var VIMEO_BASE_URL = "https://vimeo.com/api/oembed.json?url=";
var yourTestUrl = "https://vimeo.com/23374724";
$.ajax({
url: VIMEO_BASE_URL + yourTestUrl,
type: 'GET',
success: function(data) {
if (data != null && data.video_id > 0)
// Valid Vimeo url
else
// not a valid Vimeo url
},
error: function(data) {
// not a valid Vimeo url
}
});
Ответ 7
3) Ваше регулярное выражение не соответствует https url. Я не тестировал его, но я думаю, что часть "http://" станет "http (s)?://". Обратите внимание, что это изменит совпадающие позиции провайдера и идентификатора.
Ответ 8
На всякий случай, это версия php
/*
* parseVideo
* @param (string) $url
* mi-ca.ch 27.05.2016
* parse vimeo & youtube id
* format url for iframe embed
* https://regex101.com/r/lA0fP4/1
*/
function parseVideo($url) {
$re = "/(http:|https:|)\\/\\/(player.|www.)?(vimeo\\.com|youtu(be\\.com|\\.be|be\\.googleapis\\.com))\\/(video\\/|embed\\/|watch\\?v=|v\\/)?([A-Za-z0-9._%-]*)(\\&\\S+)?/";
preg_match($re, $url, $matches);
if(strrpos($matches[3],'youtu')>-1){
$type='youtube';
$src='https://www.youtube.com/embed/'.$matches[6];
}else if(strrpos($matches[3],'vimeo')>-1){
$type="vimeo";
$src='https://player.vimeo.com/video/'.$matches[6];
}else{
return false;
}
return array(
'type' => $type // return youtube or vimeo
,'id' => $matches[6] // return the video id
,'src' => $src // return the src for iframe embed
);
}
Ответ 9
Я основывал себя на предыдущих ответах, но мне нужно было больше из регулярных выражений.
Возможно, это сработало в 2011 году, но в 2019 году синтаксис немного изменился. Так что это обновление.
Регулярное выражение позволит нам определить, является ли URL-адрес Youtube или Vimeo. Я добавил группу Capture, чтобы легко получить videoID.
Если выполняется с настройкой без учета регистра, удалите (? I).
(?:(?i)(?:https:|http:)?\/\/)?(?:(?i)(?:www\.youtube\.com\/(?:embed\/|watch\?v=)|youtu\.be\/|youtube\.googleapis\.com\/v\/)(?<YoutubeID>[a-z0-9-_]{11,12})|(?:vimeo\.com\/|player\.vimeo\.com\/video\/)(?<VimeoID>[0-9]+))
https://regex101.com/r/PVdjg0/2