项目中有遇到一个需求,在前台判断用户输入的URL是否正确,如果用户输入的不是有效URL,则弹出错误提示。因为正则表达式很久没用了,同时本着不重复造轮子的想法,所以去网上搜寻了一番,找到很多大神的解决方案(见这里,这里还有这里)。但是发现有点和需求不匹配,同时检验中多少有些问题。
大神的方案是通过正则直接对网址进行规则匹配,测试中有些特殊的情况明显是正确的网址,却无法测试通过,加上项目中对域名的后缀有自己的条件,因此这里换一种思路来检测。
思路
说是思路,其实很简单,首先从输入的URL字符串中取出Domain部分,然后对Domain部分进行二次匹配,虽然麻烦了一些,但是测试效果还行。
第一版
开始参考了大神的代码,直接用字符串处理函数取出Domain部分,然后用正则来判断Domain部分是否有效:
function isURL(url) {
if (url.indexOf('http://') == -1 && url.indexOf('https://') == -1) {
return false;
}
var domain;
//find & remove protocol (http, ftp, etc.) and get domain
if (url.indexOf("://") > -1) {
domain = url.split('/')[2];
}
else {
domain = url.split('/')[0];
}
//find & remove port number
domain = domain.split(':')[0];
//check domain valid
var reg = /^(.+\.)(com|edu|gov|int|mil|net|org|biz|info|name|museum|coop|aero|[a-z][a-z])$/;
if (!reg.test(domain)) {
return false;
}
else {
return true;
}
}
这样基本实现了功能。
第二版
前面的方法看起来似乎比较麻烦。再换个思路,为什么不用正则直接解析出Domain呢,解析url各部分的正则参考了这里,下面是更新后的版本:
function isURL(url) {
var re1 = /(\w+):\/\/([^\:|\/]+)(\:\d*)?(.*\/)([^#|\?|\n]+)?(#.*)?(\?.*)?/i;
//re.exec(url);
var arr = url.match(re1);
if (arr) {
var domain = arr[2];
var re2 = /^(.+\.)(com|edu|gov|int|mil|net|org|biz|info|name|museum|coop|aero|[a-z][a-z])$/;
if (!re2.test(domain)) {
return false;
}
else {
return true;
}
} else {
return false;
}
}
这样基本实现了功能。
结束与参考
对正则的学习和理解还需要继续深入,这里的这篇文章简单的介绍了一些正则的基础,也可以看看这里。
如果这里介绍的方法有出现bug或者有更好的解决方法,欢迎留言,我会继续在这篇文章里更新。
还不快抢沙发