Javascript 改进用于解析YouTube/Vimeo URL的正则表达式
我制作了一个函数(JavaScript),它从YouTube或Vimeo获取URL。它计算出特定视频的提供者和ID(演示:) 不过,作为一名regex新手,我正在寻找改进的方法。我处理的输入通常如下所示:Javascript 改进用于解析YouTube/Vimeo URL的正则表达式,javascript,regex,youtube,vimeo,Javascript,Regex,Youtube,Vimeo,我制作了一个函数(JavaScript),它从YouTube或Vimeo获取URL。它计算出特定视频的提供者和ID(演示:) 不过,作为一名regex新手,我正在寻找改进的方法。我处理的输入通常如下所示: http://vimeo.com/(id) http://youtube.com/watch?v=(id)&blahblahblah..... 1) 现在我正在做三个独立的匹配,尝试在一个表达式中完成所有操作是否有意义?如果是,怎么做 2) 现有的匹配是否更简洁?它们是否过于复杂?或
http://vimeo.com/(id)
http://youtube.com/watch?v=(id)&blahblahblah.....
1) 现在我正在做三个独立的匹配,尝试在一个表达式中完成所有操作是否有意义?如果是,怎么做
2) 现有的匹配是否更简洁?它们是否过于复杂?或者可能不够
3) 是否有任何YouTube或Vimeo URL无法解析?我已经试过很多次了,到目前为止似乎效果不错
总而言之:我只是在寻找改进上述功能的方法。非常感谢您的建议。我不确定您的问题3),但如果您对url表单的归纳是正确的,则可以将正则表达式组合为一个,如下所示:
/http:\/\/(?:www.)?(?:(vimeo).com\/(.*)|(youtube).com\/watch\?v=(.*?)&)/
你将在不同的位置获得比赛(如果vimeo,第一场和第二场比赛,如果youtube,第三场和第四场比赛),所以你只需要处理这个问题
或者,如果您非常确定vimeo的id只包含数字,那么您可以执行以下操作:
/http:\/\/(?:www.)?(vimeo|youtube).com\/(?:watch\?v=)?(.*?)(?:\z|&)/
提供者和id将分别在第一次和第二次匹配时通知。这是我的正则表达式
关于萨瓦的回答:
第二个正则表达式的一些更新:
/http:\/\/(?:www\.)?(vimeo|youtube)\.com\/(?:watch\?v=)?(.*?)(?:\z|$|&)/
(转义点会阻止匹配类型为www_vimeo_com/…和$added…)的url)
以下是匹配嵌入URL的相同想法:
/http:\/\/(?:www\.|player\.)?(vimeo|youtube)\.com\/(?:embed\/|video\/)?(.*?)(?:\z|$|\?)/
正则表达式非常简洁,但很快就会变得复杂。
有时候,简单的代码对您的开发伙伴来说更好。
您更喜欢更新哪一个?下面是我在正则表达式中的尝试,它涵盖了大多数更新的情况:
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(/(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) 您的正则表达式与https url不匹配。我还没有测试它,但我猜“http://”部分将变成“http(s)?://”。请注意,这将更改提供者和id的匹配位置。以防这里是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
);
}
对于Vimeo,不要依赖于Regex,因为Vimeo往往会不时更改/更新其URL模式。截至2017年10月2日,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来验证vimeo URL。这是一个oEmbed()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
}
});
我基于之前的答案,但我需要更多的正则表达式 也许它在2011年起作用,但在2019年,语法发生了一些变化。这是一次刷新 正则表达式将允许我们检测url是Youtube还是Vimeo。 我添加了捕获组,以便轻松检索视频ID 如果使用不区分大小写的设置运行,请删除(?i)
(?:(?)(?:https:| http:)/)(?:(?)(?:www.youtube\.com\/(?:embed\/;watch\?v=);youtu\.be\/;youtube\.googleapis\.com\/v\)(?[a-z0-9-{11,12})(?:vimeo\.com\/;player\.vimeo\.com\/)/video\/)([0-9])
我有一项任务,可以添加dropbox视频。所以相同的输入应该是href,选中它并转换到可播放的链接,然后我可以插入其中
const getPlayableUrl = (url) => {
// Check youtube and vimeo
let firstCheck = 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+)?/);
if (firstCheck) {
if (RegExp.$3.indexOf('youtu') > -1) {
return "//www.youtube.com/embed/" + RegExp.$6;
} else if (RegExp.$3.indexOf('vimeo') > -1) {
return 'https://player.vimeo.com/video/' + RegExp.$6
}
} else {
// Check dropbox
let candidate = ''
if (url.indexOf('.mp4') !== -1) {
candidate = url.slice(0, url.indexOf('.mp4') + 4)
} else if (url.indexOf('.m4v') !== -1) {
candidate = url.slice(0, url.indexOf('.m4v') + 4)
} else if (url.indexOf('.webm') !== -1) {
candidate = url.slice(0, url.indexOf('.webm') + 5)
}
let secondCheck = candidate.match(/(http:|https:|)\/\/(player.|www.)?(dropbox\.com)\/(s\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*\/)?(.*)/);
if (secondCheck) {
return 'https://dropbox.com/' + RegExp.$4 + RegExp.$5 + RegExp.$6 + '?raw=1'
} else {
throw Error("Not supported video resource.");
}
}
}
FWIW,我只是用下面的代码来验证和解析应用程序中的YouTube和Vimeo URL。我相信你可以添加括号来解析出你正在寻找的特定内容
/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$|^(https?:\/\/)?(www.)?(player.)?vimeo.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*$/
^^这只是两个单独表达式的组合,使用|
(or)将它们连接起来。以下是两个单独的原始表达式:
/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/
/^(https?:\/\/)?(www.)?(player.)?vimeo.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*$/
我不是专家,但它似乎是根据Rubular工作的。希望这对将来的人有所帮助。哦!还有小小的URL表单:
/^http:\/\/youtu\.be\/(.+?)(?:$)/
这个正则表达式不够好,它匹配http://player.youtube.com/sdfsdfdf
这不是一个有效的youtube URL。它不适用于URL,例如。结果,我得到了对象{provider:“youtube”,id:“My2FRPA3Gf”}
。请注意id中缺少的8。有关完整的YouTube解析器,请参阅stackoverflow.com/a/5831191/208457。对于vimeo.com之类的内容,这只是一个小小的改进:(http:\/\/\\;https:\/\/\\)/12143242@flp谢谢你的建议,我已经把它合并了。你能告诉我这个url是在哪个方案下建立的吗:https://vimeo.com/334343427/4332adfeb6
fall?
(?:(?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]+))
const getPlayableUrl = (url) => {
// Check youtube and vimeo
let firstCheck = 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+)?/);
if (firstCheck) {
if (RegExp.$3.indexOf('youtu') > -1) {
return "//www.youtube.com/embed/" + RegExp.$6;
} else if (RegExp.$3.indexOf('vimeo') > -1) {
return 'https://player.vimeo.com/video/' + RegExp.$6
}
} else {
// Check dropbox
let candidate = ''
if (url.indexOf('.mp4') !== -1) {
candidate = url.slice(0, url.indexOf('.mp4') + 4)
} else if (url.indexOf('.m4v') !== -1) {
candidate = url.slice(0, url.indexOf('.m4v') + 4)
} else if (url.indexOf('.webm') !== -1) {
candidate = url.slice(0, url.indexOf('.webm') + 5)
}
let secondCheck = candidate.match(/(http:|https:|)\/\/(player.|www.)?(dropbox\.com)\/(s\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*\/)?(.*)/);
if (secondCheck) {
return 'https://dropbox.com/' + RegExp.$4 + RegExp.$5 + RegExp.$6 + '?raw=1'
} else {
throw Error("Not supported video resource.");
}
}
}
/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$|^(https?:\/\/)?(www.)?(player.)?vimeo.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*$/
/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/
/^(https?:\/\/)?(www.)?(player.)?vimeo.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*$/