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

Posted

技术标签:

【中文标题】正则表达式 - 提取子域和域【英文标题】:Regular Expression - Extract subdomain & domain 【发布时间】:2014-10-31 10:32:24 【问题描述】:

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

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

现在,我只是考虑使用 http、https 作为协议并排除“www”。来自 URL 的子域 + 域部分的部分。我检查了表达式,它几乎可以工作。但是,这里是问题:

成功

'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 => ma​​il.google.com

【问题讨论】:

【参考方案1】:

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

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

RegEx Demo

【讨论】:

【参考方案2】:

您大约是第 100 万个尝试用 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、How do I parse a URL into hostname and path in javascript? 或 parse URL with JavaScript or jQuery。你是怎么错过这些的?抱歉,我必须投票才能将其作为重复项关闭。

【讨论】:

我不需要库。我知道可用于解析 URL 的库。我需要一个正则表达式。我面临的情况是,我无法继续编写 JavaScript 代码。该函数采用正则表达式、选项和正则表达式的值作为参数并返回第一个匹配项。 太好了,祝您在未来几年重新发明***并维护您损坏的正则表达式。顺便问一下,“不能继续写javascript代码”是什么意思? 我的意思是,我不能将 javascript 代码作为参数发送。我需要传递正则表达式 那就用这个:var urlRegex = '^(?!mailto:)(?:(?:http|https|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d1,2|2[0-4]\\d|25[0-5]))2(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]2,)))|localhost)(?::\\d2,5)?(?:(/|\\?|#)[^\\s]*)?$'; 此代码不在浏览器端使用。它在 node.js 中使用。是的,node.js 有可以使用的“url”模块。但是,不幸的是,由于前面所述的原因,我无法使用它。您的正则表达式会处理我们将要遇到的大多数 URL 类型。非常感谢。【参考方案3】:

与anubhava's answer 相同的正则表达式,仅添加了对protocol-relative URLs 的支持,如//google.com

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

RegEx Demo

【讨论】:

【参考方案4】:

这是一个忽略://之前的所有内容的解决方案

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

如果你想忽略www.

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

【讨论】:

不错。谢谢。但是,我也需要忽略“www”。部分。我该怎么做? 所以,最终的正则表达式是.*\:\/\/(?:www.)?([^\/]+) “?”的用途是什么?在 (?:www.) 服务之后?我很好奇。顺便感谢您的帮助:) 看看这个regular-expressions.info/optional.html【参考方案5】:

您的正则表达式运行良好。您只需要删除括号。最后的表达式是:

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

希望有用!

【讨论】:

【参考方案6】:

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

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

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

这是above regex的链接。

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

注意:regex 比语言内置模块更快。查看下面的示例,regex 比内置模块快 15x

带有正则表达式的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 内置 url 模块

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

【讨论】:

以上是关于正则表达式 - 提取子域和域的主要内容,如果未能解决你的问题,请参考以下文章

用于自定义电子邮件和域的 C# 正则表达式

正则表达式匹配匹配域的所有子域

c# 正则表达式提取()中的值

正则表达式 提取内容

js 如何用正则表达式提取数据

正则表达式如何提取中间的数字?