我想匹配的只是一个URL的根,而不是一个文本字符串的整个URL。考虑到:

http://www.youtube.com/watch?v=ClkQA2Lb_iE
http://youtu.be/ClkQA2Lb_iE
http://www.example.com/12xy45
http://example.com/random

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

我听说正则表达式很慢,这将是我在页面上的第二个正则表达式,所以如果有办法做到没有正则表达式,请告诉我。

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


当前回答

这个解决方案工作得很好,如果URL包含大量无效字符,您也可以使用。

安装PSL包

npm install --save psl

实现

const psl = require('psl');

const url= new URL('http://www.youtube.com/watch?v=ClkQA2Lb_iE').hostname;
const parsed = psl.parse(url);

console.log(解析)

输出:

{
  input: 'www.youtube.com',
  tld: 'com',
  sld: 'youtube',
  domain: 'youtube.com',
  subdomain: 'www',
  listed: true
}

其他回答

我给你3个可能的解决方案:

使用npm包psl提取你扔给它的任何东西。 使用我的自定义实现extractRootDomain,它适用于大多数情况。 网址(URL)。主机名是可行的,但并非适用于所有边缘情况。点击“运行代码段”查看它是如何运行的。

1. 使用npm包psl(公共后缀列表)

“公共后缀列表”是所有有效域名后缀和规则的列表,不仅是国家代码顶级域名,还包括被视为根域的unicode字符(即www.食狮.公司.cn, b.c.a bebe .jp等)。点击这里阅读更多信息。

Try:

npm install --save psl

然后用我的“extractHostname”实现运行:

let psl = require('psl');
let url = 'http://www.youtube.com/watch?v=ClkQA2Lb_iE';
psl.get(extractHostname(url)); // returns youtube.com

2. extractRootDomain的自定义实现

下面是我的实现,它还针对各种可能的URL输入运行。

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; } // 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; } const urlHostname = url => { try { return new URL(url).hostname; } catch(e) { return e; } }; const urls = [ "http://www.blog.classroom.me.uk/index.php", "http://www.youtube.com/watch?v=ClkQA2Lb_iE", "https://www.youtube.com/watch?v=ClkQA2Lb_iE", "www.youtube.com/watch?v=ClkQA2Lb_iE", "ftps://ftp.websitename.com/dir/file.txt", "websitename.com:1234/dir/file.txt", "ftps://websitename.com:1234/dir/file.txt", "example.com?param=value", "https://facebook.github.io/jest/", "//youtube.com/watch?v=ClkQA2Lb_iE", "www.食狮.公司.cn", "b.c.kobe.jp", "a.d.kyoto.or.jp", "http://localhost:4200/watch?v=ClkQA2Lb_iE" ]; const test = (method, arr) => console.log( `=== Testing "${method.name}" ===\n${arr.map(url => method(url)).join("\n")}\n`); test(extractHostname, urls); test(extractRootDomain, urls); test(urlHostname, urls);

无论是否有协议或端口号,您都可以提取域。这是一个非常简化的,非正则表达式的解,所以我认为这可以解决我们在问题中提供的数据集。

3. 网址(URL) hostname

网址(URL)。主机名是一个有效的解决方案,但它不适用于我已经解决的一些边缘情况。正如您在上次测试中看到的,它不喜欢某些url。你绝对可以使用我的解决方案的组合来让它全部工作。

*感谢@Timmerz, @renoirb, @rineez, @BigDong, @ra00l, @ILikeBeansTacos, @CharlesRobertson的建议!@ross-allen,谢谢你报告这个bug!

不需要解析字符串,只需将URL作为参数传递给URL构造函数:

const url = 'http://www.youtube.com/watch?v=ClkQA2Lb_iE';
const { hostname } = new URL(url);

console.assert(hostname === 'www.youtube.com');
// use this if you know you have a subdomain
// www.domain.com -> domain.com
function getDomain() {
  return window.location.hostname.replace(/([a-zA-Z0-9]+.)/,"");
}

这不是一个完整的答案,但下面的代码应该会帮助你:

function myFunction() {
    var str = "https://www.123rf.com/photo_10965738_lots-oop.html";
    matches = str.split('/');
    return matches[2];
}

我想有人比我更快地创建代码。它也有助于提高我自己。

一个不用正则表达式的小技巧:

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中获取域部分的绝佳方法。

function url_domain(data) {
  var    a      = document.createElement('a');
         a.href = data;
  return a.hostname;
}