let link = "http://username:password@host:8080/working-tree/xux-js/src/web/tests/test.html?fruit=kiwiFruit&fruit=apricot&fruites=strawberry&fruit=persimmon&fruit=kumquat&fruit=cherry&fruites=pomegranate#large#light";
// 分布提取,繁琐
function linktext(link) {
let linkInfo = {};
linkInfo.protocol = link.match(/^(\w+):\/\//)[1]; // [0] 是整个表达式匹配的结果 [1] 是()捕获的内容 即 http
let userInfo = link.match(/\/\/([^@]+)@/); // [0] 是整个表达式匹配的结果 [1] 是用户信息
linkInfo.username = userInfo ? userInfo[1].split(':')[0] : undefined;
linkInfo.password = userInfo ? userInfo[1].split(':')[1] : undefined;
let yuming = link.match(/:\/\/([^@]+@)?([\w.]+):?(\d+)?\/?/); // [0]是整个表达式匹配的结果 [1] 是用户信息 [2] 是域名 [3] 是端口号 8080
if (!yuming[3]) {
let defaultPortNumber = { http: '80', https: '443' };
yuming[3] = defaultPortNumber[linkInfo.protocol]; // 当端口号为空时,修改为对应域名默认的端口号
}
linkInfo.IP = yuming[2];
linkInfo.port = yuming[3];
let fileNameReg = link.match(/:\/\/[\w\W]+\/([\w.-]+)\??#?[^\/]*$/);
linkInfo.filename = fileNameReg ? fileNameReg[1] : undefined; // [0] 整个表达式匹配的结果 [1] 文件名
let pathReg = link.match(/[\w.]+:?(\d+)?\/([\w-\/]+\/)/); // [0] 整个表达式匹配的结果 [1] 端口号 [2] 虚拟路径
linkInfo.path = pathReg ? fileNameReg ? pathReg[2] + fileNameReg[1] : pathReg[2] : undefined;
let queryReg = link.match(/\?([^#]+)#?/); // [0] 整个表达式匹配的结果 [1] 查询参数
let query;
if (queryReg) {
query = {};
queryReg[1].split('&').forEach(v => {
let res = v.split('=');
// 如果有查询参数,并且查询参数具有相同属性时,将对应参数的值转为数组表示
query[res[0]] = query[res[0]] ? [query[res[0]], res[1]].flat() : res[1];
});
}
linkInfo.query = query;
let fragment = link.match(/#([\w\W]+)$/);
linkInfo.ref = fragment ? fragment[1].split('#') : undefined;
return linkInfo;
}
linktext(link);
正则一时爽
let link = "http://username:password@host:8080/working-tree/xux-js/src/web/tests/test.html?fruit=kiwiFruit&fruit=apricot&fruites=strawberry&fruit=persimmon&fruit=kumquat&fruit=cherry&fruites=pomegranate#large#light";
// 一次提取出全部内容
function linkInfo(link) {
let queryRes = link.match(/^(\w+):\/\/([^@]+@)?([\w.]+):?(\d+)?\/?([\w-\/]+\/)?([\w.-]+)?\??([^#]+)?#?([\w\W]+)?$/),
defaultPortNumber = { http: '80', https: '443' },
query;
if (queryRes[7]) {
query = {};
queryRes[7].split('&').forEach(v => {
let res = v.split('=');
query[res[0]] = query[res[0]] ? [query[res[0]], res[1]].flat() : res[1];
});
}
return {
protocol: queryRes[1],
username: queryRes[2] && queryRes[2].split(':')[0],
password: queryRes[2] && queryRes[2].split(':')[1].replace('@', ''),
IP: queryRes[3],
port: queryRes[4] || defaultPortNumber[queryRes[1]],
path: queryRes[5] + queryRes[6] || '',
filename: queryRes[6],
query: query,
ref: queryRes[8].split('#')
};
}
linkInfo(link)