首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >从字符串中提取主机名

从字符串中提取主机名
EN

Stack Overflow用户
提问于 2011-12-14 09:36:42
回答 21查看 310.7K关注 0票数 295

我希望只匹配URL的根,而不是文本字符串中的整个URL。给定:

代码语言:javascript
复制
http://www.youtube.com/watch?v=ClkQA2Lb_iE
http://youtu.be/ClkQA2Lb_iE
http://www.example.com/12xy45
http://example.com/random

我想让最后两个实例解析到www.example.comexample.com域。

我听说正则表达式很慢,这将是我在页面上的第二个正则表达式,所以如果有任何方法可以不使用正则表达式,请告诉我。

我正在寻找这个解决方案的JS/jQuery版本。

EN

回答 21

Stack Overflow用户

回答已采纳

发布于 2014-05-30 08:06:21

我推荐使用npm包psl (Public Suffix List)。“公共后缀列表”是所有有效的域后缀和规则的列表,不仅包括国家代码顶级域,还包括将被视为根域的unicode字符(即www.食狮.公司.cn、b.c.kobe.jp等)。有关它的更多信息,请阅读here

尝试:

代码语言:javascript
复制
npm install --save psl

然后运行我的"extractHostname“实现:

代码语言:javascript
复制
let psl = require('psl');
let url = 'http://www.youtube.com/watch?v=ClkQA2Lb_iE';
psl.get(extractHostname(url)); // returns youtube.com

我不能使用npm包,所以下面只测试extractHostname。

代码语言:javascript
复制
function extractHostname(url) {
    var hostname;
    //find & remove protocol (http, ftp, etc.) and get hostname

    if (url.indexOf("//") > -1) {
        hostname = url.split('/')[2];
    }
    else {
        hostname = url.split('/')[0];
    }

    //find & remove port number
    hostname = hostname.split(':')[0];
    //find & remove "?"
    hostname = hostname.split('?')[0];

    return hostname;
}

//test the code
console.log("== Testing extractHostname: ==");
console.log(extractHostname("http://www.blog.classroom.me.uk/index.php"));
console.log(extractHostname("http://www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("https://www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("ftps://ftp.websitename.com/dir/file.txt"));
console.log(extractHostname("websitename.com:1234/dir/file.txt"));
console.log(extractHostname("ftps://websitename.com:1234/dir/file.txt"));
console.log(extractHostname("example.com?param=value"));
console.log(extractHostname("https://facebook.github.io/jest/"));
console.log(extractHostname("//youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("http://localhost:4200/watch?v=ClkQA2Lb_iE"));

// Warning: you can use this function to extract the "root" domain, but it will not be as accurate as using the psl package.

function extractRootDomain(url) {
    var domain = extractHostname(url),
        splitArr = domain.split('.'),
        arrLen = splitArr.length;

    //extracting the root domain here
    //if there is a subdomain 
    if (arrLen > 2) {
        domain = splitArr[arrLen - 2] + '.' + splitArr[arrLen - 1];
        //check to see if it's using a Country Code Top Level Domain (ccTLD) (i.e. ".me.uk")
        if (splitArr[arrLen - 2].length == 2 && splitArr[arrLen - 1].length == 2) {
            //this is using a ccTLD
            domain = splitArr[arrLen - 3] + '.' + domain;
        }
    }
    return domain;
}

//test extractRootDomain
console.log("== Testing extractRootDomain: ==");
console.log(extractRootDomain("http://www.blog.classroom.me.uk/index.php"));
console.log(extractRootDomain("http://www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractRootDomain("https://www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractRootDomain("www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractRootDomain("ftps://ftp.websitename.com/dir/file.txt"));
console.log(extractRootDomain("websitename.co.uk:1234/dir/file.txt"));
console.log(extractRootDomain("ftps://websitename.com:1234/dir/file.txt"));
console.log(extractRootDomain("example.com?param=value"));
console.log(extractRootDomain("https://facebook.github.io/jest/"));
console.log(extractRootDomain("//youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractRootDomain("http://localhost:4200/watch?v=ClkQA2Lb_iE"));

无论是否具有协议或端口号,您都可以提取域。这是一个非常简单的、非正则表达式的解决方案,所以我认为这样就可以了。

*感谢您@Timmerz,@renoirb,@rineez,@BigDong,@ra00l,@ILikeBeansTacos,@CharlesRobertson的建议!@ross-allen,感谢您报告错误!

票数 312
EN

Stack Overflow用户

发布于 2011-12-14 09:48:31

不使用正则表达式的巧妙技巧:

代码语言:javascript
复制
var tmp        = document.createElement ('a');
;   tmp.href   = "http://www.example.com/12xy45";

// tmp.hostname will now contain 'www.example.com'
// tmp.host will now contain hostname and port 'www.example.com:80'

将上面的内容封装在下面这样的函数中,您就拥有了一种从URI中获取域部分的绝佳方法。

代码语言:javascript
复制
function url_domain(data) {
  var    a      = document.createElement('a');
         a.href = data;
  return a.hostname;
}
票数 338
EN

Stack Overflow用户

发布于 2016-02-05 19:22:11

不需要解析字符串,只需将URL作为参数传递给URL constructor即可

代码语言:javascript
复制
const url = 'http://www.youtube.com/watch?v=ClkQA2Lb_iE';
const { hostname } = new URL(url);

console.assert(hostname === 'www.youtube.com');
票数 228
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8498592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档