正则表达式 - 提取子域和域
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 => mail.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的链接。
如果你想得到subdomain
、split
的结果来自上述正则表达式与.
第一次出现的匹配项
注意: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
【讨论】:
以上是关于正则表达式 - 提取子域和域的主要内容,如果未能解决你的问题,请参考以下文章