如何在JavaScript中从URL中提取主机名?

27
捕获域名,直到结束字符$, \?, /, :。我需要一个正则表达式来在这些情况下都捕获example.com
example.com:3000
example.com?pass=gas
example.com/
example.com

@macek 我为 JavaScript 构建了一个 URL / URI 构建器,它可以接受参数并从对象构建 URL。我正在寻找创建一个正则表达式,可以将字符串转换为对象的方法。http://stackoverflow.com/questions/13498417/build-urls-from-json - ThomasReggi
我在这里发布了我的模块 https://github.com/reggi/schemejs - ThomasReggi
6个回答

57

如果您实际上拥有有效的URL,这将有效:

var urls = [
    'http://example.com:3000',
    'http://example.com?pass=gas',
    'http://example.com/',
    'http://example.com'
];

for (x in urls) {
    var a = document.createElement('a');
    a.href = urls[x];
    console.log(a.hostname);
}

//=> example.com
//=> example.com
//=> example.com
//=> example.com

注意,当你使用的语言有其他内置方法时,为这种事情使用正则表达式是愚蠢的。

A 元素上可用的其他属性。

var a = document.createElement('a');
a.href = "http://example.com:3000/path/to/something?query=string#fragment"

a.protocol   //=> http:
a.hostname   //=> example.com
a.port       //=> 3000
a.pathname   //=> /path/to/something
a.search     //=> ?query=string
a.hash       //=> #fragment
a.host       //=> example.com:3000

编辑 #2

经过进一步考虑,我查阅了Node.js文档,并找到了这个小宝石:url#parse

上面的代码可以改写为:

var url = require('url');

var urls = [
    'http://example.com:3000',
    'http://example.com?pass=gas',
    'http://example.com/',
    'http://example.com'
];

for (x in urls) {
    console.log(url.parse(urls[x]).hostname);
}

//=> example.com
//=> example.com
//=> example.com
//=> example.com

编辑 #1

如果您想了解如何使用jsdomnodejs解决此问题,请查看此帖子的修订历史记录


JavaScript,但我真的只想要一个正则表达式。 - ThomasReggi
我在处理。是的。现在有点晚了,标签非常好用。谢谢。 - ThomasReggi
4
@ThomasReggi,我发现nodejs有自己的url#parse方法。请参见上面的编辑#2 - maček
1
使用 DOM 对象不是 JS 的特性,而是 DOM 绑定的特性。在许多 JS 环境中并不存在 DOM。此外,它也非常慢,执行简单字符串解析的正确方式就是使用正则表达式。 - stroncium
主机名包括子域名。 - Muhammad Umer
显示剩余6条评论

31

由于您正在使用Node,只需使用内置的 url.parse() 方法即可;您需要的是返回的 hostname 属性:

var url=require('url');
var urls = [
  'http://example.com:3000',
  'http://example.com?pass=gas',
  'http://example.com/',
  'http://example.com'
];

urls.forEach(function(x) {
  console.log(url.parse(x).hostname);
});

返回:{ pathname: '0', path: '0', href: '0' } { pathname: '1', path: '1', href: '1' } { pathname: '2', path: '2', href: '2' } { pathname: '3', path: '3', href: '3' } - ThomasReggi
测试工具搞砸了(从另一个答案复制过来的),在我的答案中进行了更新。教训是:不要使用for (...in...)来遍历数组。 - ebohlman
3
它包括子域名。 - Muhammad Umer
@MuhammadUmer 子域名是主机名的一部分。 - Jakub Keller

27

6

我正在使用Node ^10,以下是我从URL中提取主机名的方法。

var url = URL.parse('https://dev59.com/c2Yr5IYBdhLWcg3wpbyQ')
console.log(url.hostname)
//=> stackoverflow.com

1

我建议使用现在大多数浏览器都包含的新 URL 类

var urls = [
  'http://example.com:3000',
  'http://example.com?pass=gas',
  'http://example.com/',
  'http://example.com'
];

urls.forEach(url => {
  const u = new URL(url)
  console.log(u.hostname)
})


0
/^((?:[a-z0-9-_]+\.)*[a-z0-9-_]+\.?)(?::([0-9]+))?(.*)$/i

匹配项包括主机、端口和路径。


不起作用:s="https://dev59.com/c2Yr5IYBdhLWcg3wpbyQ" s.match(/^((?:[a-z0-9-]+.)*[a-z0-9-]+.?)(?::([0-9]+))?(.*)$/i) 的结果如下: ["https://dev59.com/c2Yr5IYBdhLWcg3wpbyQ", "http", undefined, "://stackoverflow.com/questions/13506460/how-to-extract-the-host-from-a-url-in-javascript"] - xShirase
请勿发布虚假测试。你的结果包含字符串“http”作为匹配字符串,而你说你运行正则表达式的字符串不包含“http”子字符串。你要么修补了执行结果,要么修改了你的JS虚拟机的源代码才能实现这个结果。 "stackoverflow.com/questions/13506460/how-to-extract...".match(/^((?:[a-z0-9-]+\.)*[a-z0-9-]+\.?)(?::([0-9]+))?(.*)$/i) 完美地工作,结果为 ["stackoverflow.com/questions/13506460/how-to-extract...", "stackoverflow.com", undefined, "/questions/13506460/how-to-extract..."] - stroncium
不好意思,stackoverflow自动切断了链接...现在,请检查这个fiddle:http://jsfiddle.net/WLGmv/,并让我知道我是否做错了什么。 - xShirase
当然。您试图将此正则表达式用于错误的目的。如果您重新阅读原始问题,它不应该做您想要的事情。您需要使用URI方案解析URL,请尝试使用此代码:/^(?:https?:\/\/)?((?:[a-z0-9-_]+\.)*[a-z0-9-_]+\.?)(?::([0-9]+))?(.*)$/i(仅适用于http和https或根本没有URI方案)。Fiddle在这里:http://jsfiddle.net/WLGmv/1/ - stroncium

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接