我想匹配的只是一个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版本。


当前回答

试试这个:

var matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
var domain = matches && matches[1];  // domain will be null if no match is found

如果你想从结果中排除端口,请使用下面的表达式:

/^https?\:\/\/([^\/:?#]+)(?:[\/:?#]|$)/i

编辑:要防止特定域匹配,请使用反向前向。(? ! youtube.com)

/^https?\:\/\/(?!(?:www\.)?(?:youtube\.com|youtu\.be))([^\/:?#]+)(?:[\/:?#]|$)/i

其他回答

好吧,我知道这是一个老问题,但我做了一个超级高效的url解析器,所以我想我要分享它。

如你所见,这个函数的结构很奇怪,但这是为了提高效率。不使用原型函数,字符串迭代次数不超过一次,处理字符的次数也不超过必要的次数。

function getDomain(url) {
    var dom = "", v, step = 0;
    for(var i=0,l=url.length; i<l; i++) {
        v = url[i]; if(step == 0) {
            //First, skip 0 to 5 characters ending in ':' (ex: 'https://')
            if(i > 5) { i=-1; step=1; } else if(v == ':') { i+=2; step=1; }
        } else if(step == 1) {
            //Skip 0 or 4 characters 'www.'
            //(Note: Doesn't work with www.com, but that domain isn't claimed anyway.)
            if(v == 'w' && url[i+1] == 'w' && url[i+2] == 'w' && url[i+3] == '.') i+=4;
            dom+=url[i]; step=2;
        } else if(step == 2) {
            //Stop at subpages, queries, and hashes.
            if(v == '/' || v == '?' || v == '#') break; dom += v;
        }
    }
    return dom;
}

有两个很好的解决方案,这取决于你是否需要优化性能(并且没有外部依赖!):

1. 使用URL。便于阅读的主机名

最简洁和最简单的解决方案是使用URL.hostname。

getHostname = (url) => { //使用URL构造函数并返回主机名 返回新URL(URL).hostname; } / /测试 console.log (getHostname (" https://stackoverflow.com/questions/8498592/extract-hostname-name-from-string/ ")); console.log (getHostname (" https://developer.mozilla.org/en-US/docs/Web/API/URL/hostname "));

URL。主机名是URL API的一部分,除IE (caniuse)之外的所有主流浏览器都支持。如果需要支持旧浏览器,请使用URL填充。

额外的好处:使用URL构造函数还可以让你访问其他URL属性和方法!


2. 使用RegEx来提高性能

URL。对于大多数用例,主机名应该是您的选择。然而,它仍然比这个正则表达式慢得多(你自己在jsPerf上测试):

const getHostnameFromRegex = (url) => { //运行正则表达式 const匹配= url.match (/ ^ https ?\:\/\/([^\/?#]+)(?:[\/?#]|$)/ 我); //提取主机名(如果没有匹配则为空) 返回匹配&&匹配[1]; } / /测试 console.log (getHostnameFromRegex (" https://stackoverflow.com/questions/8498592/extract-hostname-name-from-string/ ")); console.log (getHostnameFromRegex (" https://developer.mozilla.org/en-US/docs/Web/API/URL/hostname "));


博士TL;

你应该使用URL.hostname。如果您需要处理大量的url(其中性能是一个因素),请考虑RegEx。

function hostname(url) {
    var match = url.match(/:\/\/(www[0-9]?\.)?(.[^/:]+)/i);
    if ( match != null && match.length > 2 && typeof match[2] === 'string' && match[2].length > 0 ) return match[2];
}

上面的代码将成功解析以下示例url的主机名: http://WWW.first.com/folder/page.html first.com http://mail.google.com/folder/page.html mail.google.com https://mail.google.com/folder/page.html mail.google.com http://www2.somewhere.com/folder/page.html?q=1 somewhere.com https://www.another.eu/folder/page.html?q=1 another.eu

原文出处:http://www.primaryobjects.com/CMS/Article145

只需使用URL()构造函数:

new URL(url).host

这个解决方案工作得很好,如果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
}