正则表达式 - 提取子域和域

Regular Expression - Extract subdomain & domain

本文关键字:提取 正则表达式      更新时间:2023-09-26

>我正在尝试形成一个正则表达式(javascript/node.js(,它将从任何给定的URL中提取子域和域部分。这就是我最终得到的:

[^(?:http:'/'/|www'.|https:'/'/)]([^'/]+)

现在,我只是在考虑http,https协议并从URL的子域+域部分排除"www."部分。我检查了表达式,它几乎有效。但是,问题来了:

成功

'http://mplay.google.co.in/sadfask/asdkfals?dk=10'.match(/[^(?:http:'/'/|www'.|https:'/'/)]([^'/]+)/i)
'http://lplay.google.co.in/sadfask/asdkfals?dk=10'.match(/[^(?:http:'/'/|www'.|https:'/'/)]([^'/]+)/i)

失败

'http://play.google.co.in/sadfask/asdkfals?dk=10'.match(/[^(?:http:'/'/|www'.|https:'/'/)]([^'/]+)/i)
'http://tplay.google.co.in/sadfask/asdkfals?dk=10'.match(/[^(?:http:'/'/|www'.|https:'/'/)]([^'/]+)/i)

我只使用结果数组中的第一个元素。我不明白为什么"玩"和"玩"不起作用。谁能在这方面帮助我?

"/

p"和"/t"对正则表达式计算器有什么意义吗?

有没有其他方法可以使用正则表达式从任何给定的URL中提取子域和域?

编辑-

例:

https://play.google.com/store/apps/details?id=com.skgames.trafficracer => play.google.com

https://mail.google.com/mail/u/0/#inbox => mail.google.com

您的正则表达式似乎不正确。试试这个正则表达式:

/^(?:https?:'/'/)?(?:[^@'n]+@)?(?:www'.)?([^:'/'n?]+)/img

正则表达式演示

您是尝试在 JavaScript 中解析 URL 的第一百万个人。我有点惊讶你没有看到任何关于SO的现有问题,可以追溯到几年前。您要做的最后一件事是编写另一个损坏的正则表达式,并充分尊重那些为您的问题提供答案的人。

有许多文档齐全的库和方法来处理这个问题。谷歌一下。最简单的方法是在内存中创建 a 元素,为其分配一个href,然后访问其hostname和其他属性。请参阅 http://tutorialzine.com/2013/07/quick-tip-parse-urls/。如果这不能漂浮你的船,那么使用像uri.js这样的库。

如果你真的不想使用库,并坚持重新发明轮子,那么至少做如下事情:

function get_domain_from_url(url) {
    var a = document.createElement('a').
    a.setAttribute('href', url);
    return a.hostname;
}

从本质上讲,您将 URL 的子域/域部分的提取委托给浏览器的 URL 解析逻辑,这比您编写的任何内容都要好得多。

另请参阅 Parse URL with jquery/javascript?、Parse URL with Javascript、如何在 javascript 中将 URL 解析为主机名和路径?,或使用 JavaScript 或 jQuery 解析 URL。你怎么错过了这些?抱歉,我必须投票将其作为重复项关闭。

与 anubhava 的答案相同的 RegExp,只是增加了对协议相对 URL 的支持,如 //google.com

/^(?:https?:)?(?:'/'/)?(?:[^@'n]+@)?(?:www'.)?([^:'/'n]+)/im

正则表达式演示

这是一个

忽略之前所有内容的解决方案://

.*'://?([^'/]+)

如果您想忽略www.

.*'://(?:www.)?([^'/]+)

你的正则表达式效果很好。您只需要删除括号。最后一个表达式是:

^(?:http:'/'/|www'.|https:'/'/)([^'/]+)

希望有用!

这个使用命名捕获组的 JavaScript 正则表达式将链接/URL 分解为其功能组件:

console.log("https://www.sub.domain.google.com:443/maps/place/Arc+De+Triomphe/@48.8737917,2.2928388,17z?query=1&foo#hash".match(/^(?<protocol>https?:'/'/)(?=(?<fqdn>[^:/]+))(?:(?<service>www|ww'd|cdn|ftp|mail|pop'd?|ns'd?|git)'.)?(?:(?<subdomain>[^:/]+)'.)*(?<domain>[^:/]+'.[a-z0-9]+)(?::(?<port>'d+))?(?<path>'/[^?]*)?(?:'?(?<query>[^#]*))?(?:#(?<hash>.*))?/i).groups)

输出:

{
  "protocol": "https://",
  "fqdn": "www.sub.domain.google.com",
  "service": "www",
  "subdomain": "sub.domain",
  "domain": "google.com",
  "port": "443",
  "path": "/maps/place/Arc+De+Triomphe/@48.8737917,2.2928388,17z",
  "query": "query=1&foo",
  "hash": "hash"
}

因此,您可以使用任何您喜欢的组件

我知道

我迟到了,但我想用一些额外的有用信息来回答这个问题。

使用正则表达式从链接中获取域名。

^(https?:'/'/)?(www'.)?([^'/]+)

这是上述正则表达式的链接。

如果你想得到subdomainsplit上述正则表达式的匹配之一的结果,第一次出现.

注意:regex比语言内置模块快。 查看以下示例,regex比内置模块快 15 倍

带有正则表达式的JavaScript示例:

console.time('time2');
const pttrn = /^(https?:'/'/)?(www'.)?([^'/]+)/gm
const urlInfo = pttrn.exec("https://www.google.co.in/imghp");
console.timeEnd('time2');
//time2: 0.055ms
console.log(urlInfo[0]) // https://www.google.co.in
console.log(urlInfo[1]) // https://
console.log(urlInfo[2]) // www.
console.log(urlInfo[3]) // google.co.in

带有内置网址模块的 Nodejs

console.time('time');
const url = require('url');
const urlInfo = url.parse("https://www.google.co.in/imghp");
console.timeEnd('time');
//time: 0.840ms;
console.log(urlInfo.hostname) //www.google.co.in