Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 如何从URL获取域名_Regex_Url - Fatal编程技术网

Regex 如何从URL获取域名

Regex 如何从URL获取域名,regex,url,Regex,Url,如何从URL字符串中获取域名 示例: 相关的: 我不知道有什么库,但是域名的字符串操作非常简单 困难的部分是知道这个名字是第二级还是第三级。为此,您需要维护一个数据文件,例如For.uk不一定是第三级,一些组织,例如bl.uk、jet.uk存在于第二级 来自Mozilla的有这样一个数据文件,请检查Mozilla许可证,看看是否可以重用该文件。您需要一个可以删除哪些域前缀和后缀的列表。例如: 前缀: www。 后缀: 网站 美国公司 A.非英国 我曾经为一家公司写过这样的正则表达式。解决办法是:

如何从URL字符串中获取域名

示例: 相关的:


我不知道有什么库,但是域名的字符串操作非常简单

困难的部分是知道这个名字是第二级还是第三级。为此,您需要维护一个数据文件,例如For.uk不一定是第三级,一些组织,例如bl.uk、jet.uk存在于第二级


来自Mozilla的有这样一个数据文件,请检查Mozilla许可证,看看是否可以重用该文件。

您需要一个可以删除哪些域前缀和后缀的列表。例如:

前缀:

www。 后缀:

网站 美国公司 A.非英国
我曾经为一家公司写过这样的正则表达式。解决办法是:

获取每一个可用项目的列表。你的第一站应该是。Mozilla的列表乍一看非常棒,但缺少ac.uk,因此它实际上不可用。 像下面的例子一样加入列表。警告:订购很重要!如果org.uk出现在uk之后,那么example.org.uk将匹配org而不是example。 正则表达式示例:

.*([^\.]+)(com|net|org|info|coop|int|co\.uk|org\.uk|ac\.uk|uk|__and so on__)$
这真的很好,也符合像de.com和friends这样奇怪的非官方高层

好处是:

如果正则表达式是最优排序的,则速度非常快 这种解决方案的缺点当然是:

手写正则表达式,如果CCTLD更改或添加,则必须手动更新。乏味的工作! 非常大的正则表达式,因此不太可读。 这段代码不能保证适用于所有URL,也不能过滤语法正确但无效的URL,比如“example.uk”

但是,在大多数情况下,它都能完成任务。

/[^w{3}.][a-zA-Z0-9][a-zA-Z0-9\-]{0,65}[a-zA-Z0-9]?\.+[a-zA-Z]{2,6}/gim


使用此javascript正则表达式会忽略www和下面的点,同时保持域的完整性。也没有正确匹配www和cc tld

如果不使用tld列表与它们进行比较是不可能的,因为它们存在许多类似或的情况,这些情况将被正则表达式解释为域db.de correct和co.uk error

但即使这样,如果你的列表中也没有SLD,你也不会成功。URL类似并将被解释为uk.com。第一个域名是big.uk.com

因此,所有浏览器都使用Mozilla的公共后缀列表:

通过以下URL导入,您可以在代码中使用它:

请随意扩展我的功能提取域名,只。它不会使用正则表达式,而且速度很快:


所以如果你只有一个字符串而没有一个window.location,你可以使用

String.prototype.toUrl = function(){

if(!this && 0 < this.length)
{
    return undefined;
}
var original = this.toString();
var s = original;
if(!original.toLowerCase().startsWith('http'))
{
    s = 'http://' + original;
}

s = this.split('/');

var protocol = s[0];
var host = s[2];
var relativePath = '';

if(s.length > 3){
    for(var i=3;i< s.length;i++)
    {
        relativePath += '/' + s[i];
    }
}

s = host.split('.');
var domain = s[s.length-2] + '.' + s[s.length-1];    

return {
    original: original,
    protocol: protocol,
    domain: domain,
    host: host,
    relativePath: relativePath,
    getParameter: function(param)
    {
        return this.getParameters()[param];
    },
    getParameters: function(){
        var vars = [], hash;
        var hashes = this.original.slice(this.original.indexOf('?') + 1).split('&');
        for (var i = 0; i < hashes.length; i++) {
            hash = hashes[i].split('=');
            vars.push(hash[0]);
            vars[hash[0]] = hash[1];
        }
        return vars;
    }
};};

出于某种目的,我昨天完成了这个快速Python函数。它从URL返回域。它的速度很快,不需要任何输入文件列出的东西。然而,我并不是假装它在所有情况下都能工作,但它确实完成了一个简单的文本挖掘脚本所需要的工作

输出如下所示:

=>google.co.uk =>tumblr.com

def getDomain(url):    
        parts = re.split("\/", url)
        match = re.match("([\w\-]+\.)*([\w\-]+\.\w{2,6}$)", parts[2]) 
        if match != None:
            if re.search("\.uk", parts[2]): 
                match = re.match("([\w\-]+\.)*([\w\-]+\.[\w\-]+\.\w{2,6}$)", parts[2])
            return match.group(2)
        else: return ''  
看起来效果不错。
但是,必须对其进行修改,以便根据需要删除输出上的域扩展。

基本上,您需要的是:

google.com        -> google.com    -> google
www.google.com    -> google.com    -> google
google.co.uk      -> google.co.uk  -> google
www.google.co.uk  -> google.co.uk  -> google
www.google.org    -> google.org    -> google
www.google.org.uk -> google.org.uk -> google
可选:

www.google.com     -> google.com    -> www.google
images.google.com  -> google.com    -> images.google
mail.yahoo.co.uk   -> yahoo.co.uk   -> mail.yahoo
mail.yahoo.com     -> yahoo.com     -> mail.yahoo
www.mail.yahoo.com -> yahoo.com     -> mail.yahoo
您不需要构造一个不断变化的正则表达式,因为如果您只需查看名称的最后第二部分,99%的域将正确匹配:

(co|com|gov|net|org)
如果是其中一个,则需要匹配3个点,否则为2个点。易于理解的现在,我的正则表达式魔法无法与其他一些SO'ER的相比,因此我发现实现这一点的最佳方法是使用一些代码,假设您已经删除了路径:

 my @d=split /\./,$domain;                # split the domain part into an array
 $c=@d;                                   # count how many parts
 $dest=$d[$c-2].'.'.$d[$c-1];             # use the last 2 parts
 if ($d[$c-2]=~m/(co|com|gov|net|org)/) { # is the second-last part one of these?
   $dest=$d[$c-3].'.'.$dest;              # if so, add a third part
 };
 print $dest;                             # show it
根据您的问题,仅获取名称:

 my @d=split /\./,$domain;                # split the domain part into an array
 $c=@d;                                   # count how many parts
 if ($d[$c-2]=~m/(co|com|gov|net|org)/) { # is the second-last part one of these?
   $dest=$d[$c-3];                        # if so, give the third last
   $dest=$d[$c-4].'.'.$dest if ($c>3);    # optional bit
 } else {
   $dest=$d[$c-2];                        # else the second last
   $dest=$d[$c-3].'.'.$dest if ($c>2);    # optional bit 
 };
 print $dest;                             # show it
我喜欢这种方法,因为它是免维护的。除非你想确认它实际上是一个合法的域,但这是毫无意义的,因为你很可能只是用它来处理日志文件,而一个无效的域在一开始就找不到它

如果您想匹配非官方子域,如bozo.za.net或bozo.au.uk,bozo.msf.ru只需将za | au | msf添加到正则表达式中即可

我很想看到有人只用一个正则表达式来完成所有这些,我相信这是可能的。

使用这个
/^(?:https?:\/\/)?(?:www\.)?([^\/]+)/i
..*?. 然后,只提取前导点和终点。 简单,对吗?

有两种方法

使用拆分

然后解析这个字符串

var domain;
//find & remove protocol (http, ftp, etc.) and get domain
if (url.indexOf('://') > -1) {
    domain = url.split('/')[2];
} if (url.indexOf('//') === 0) {
    domain = url.split('/')[2];
} else {
    domain = url.split('/')[0];
}

//find & remove port number
domain = domain.split(':')[0];
使用正则表达式

希望这对知识有所帮助:

'http://api.livreto.co/books'.replace(/^(https?:\/\/)([a-z]{3}[0-9]?\.)?(\w+)(\.[a-zA-Z]{2,3})(\.[a-zA-Z]{2,3})?.*$/, '$3$4$5');

# returns livreto.co 
这是怎么回事

=?:?:?:?:?\/\/\/?:?:[a-zA-Z0-9]+\.?*?:?:[a-zA-Z0-9]+\.[a-zA-Z0-9]{2,3} 您可能需要将\/添加到模式的末尾

如果您的目标是删除作为参数传入的url,则可以添加等号作为第一个字符,如:

=?:?:?:?:?//?:?:[a-zA-Z0-9]+.?*?:?:[a-zA-Z0-9]+.[a-zA-Z0-9].[a-zA-Z0-9]{2,3}/

并替换为/

本例的目标是除去任何域名,而不管它以何种形式出现。
i、 e.确保url参数不包含适当的域名以避免xss攻击

准确提取域名可能相当棘手,主要是因为域名扩展可以包含两个部分,如.com.au或.co.uk和 前缀所在的子域可能存在,也可能不存在。列出所有域扩展不是一个选项,因为有数百个这样的扩展。例如,EuroDNS.com列出了超过800个域名扩展名

因此,我编写了一个简短的php函数,它使用“parse_url”和一些关于域扩展的观察来准确提取url组件和域名。功能如下:

function parse_url_all($url){
    $url = substr($url,0,4)=='http'? $url: 'http://'.$url;
    $d = parse_url($url);
    $tmp = explode('.',$d['host']);
    $n = count($tmp);
    if ($n>=2){
        if ($n==4 || ($n==3 && strlen($tmp[($n-2)])<=3)){
            $d['domain'] = $tmp[($n-3)].".".$tmp[($n-2)].".".$tmp[($n-1)];
            $d['domainX'] = $tmp[($n-3)];
        } else {
            $d['domain'] = $tmp[($n-2)].".".$tmp[($n-1)];
            $d['domainX'] = $tmp[($n-2)];
        }
    }
    return $d;
}
这个简单的函数几乎适用于所有情况。有一些例外,但这是非常罕见的

要演示/测试此功能,您可以使用以下方法:

$urls = array('www.test.com', 'test.com', 'cp.test.com' .....);
echo "<div style='overflow-x:auto;'>";
echo "<table>";
echo "<tr><th>URL</th><th>Host</th><th>Domain</th><th>Domain X</th></tr>";
foreach ($urls as $url) {
    $info = parse_url_all($url);
    echo "<tr><td>".$url."</td><td>".$info['host'].
    "</td><td>".$info['domain']."</td><td>".$info['domainX']."</td></tr>";
}
echo "</table></div>";
所列URL的输出如下所示:

正如您所看到的,无论呈现给函数的URL是什么,都会一致地提取域名和不带扩展名的域名


我希望这会有所帮助。

我知道这个问题是在寻找一个正则表达式解决方案,但每次尝试都无法涵盖所有问题

我决定用Python编写这个方法,它只适用于具有子域(即www.mydomain.co.uk)的URL,而不适用于像www.mail.yahoo.com这样的多级子域


派对有点晚了,但是:

常量URL=[ “www.abc.au.uk”, 'https://github.com', 'http://github.ca', 'https://www.google.ru', 'http://www.google.co.uk', “www.yandex.com”, “yandex.ru”, “yandex” ]
url.forEachurl=>console.logurl.replace/+\/\/\/\124; www.|\..+//g,你能不能在.com或其他之前查找这个词?其他列表的顺序与频率相反请参见

以第一个匹配组为例 i、 e

您可以通过将这一行复制到任何选项卡上的开发人员控制台来测试它

此示例适用于以下情况:



那www.abc.def.ghi.au.uk呢?那“foo.bar.com”呢?还有“foo.com”?好吧,几分钟内的第二篇关于一个非常相似的主题的帖子——家庭作业?我可以问你为什么吗?很难发明没有二级域名后缀的域名,比如.co,你需要什么。uk@Chinmay当前位置你的术语在这里有各种各样的错误。您列出的所有输入都是域名,而不是URL。这是一个URL:http://en.wikipedia.org/wiki/URL,该URL中的域名为en.wikipedia.org,仅适用于样本,维护此类列表不会增加:更新繁琐-编写一个小代码生成器程序,根据输入数据文件生成正则表达式。True。使用良好的测试线束,这应该是可能的。我们当时当然没有做任何测试……Mozilla的列表实际上看起来相当不错——它有*.uk可匹配。ac.uk。您只需找出格式并正确解释规则。我在几个项目中需要它,所以我用Python和Java实现了它。您还可以通过AppEngine上的HTTP端点进行查询。请随意贡献!Mozilla PSL现在匹配*.uk,因此@pi.对它无法匹配ac.uk的担心不再适用。如果您在匹配运算符中使用了除正斜杠以外的其他字符,那么您就不需要有这么多转义字符,并且可以使正则表达式更具可读性,例如$url=~m{[^::]://?[^/]*.[^/\.[^/]+}你也不确定你想要循环操作符/g吗?是的,尽管我回答的最大问题是它不适用于外国域名,因为它们不遵循标准的美国格式xxx.com | edu | org |等。Sot telegraph.co.uk不会匹配。让我觉得你真的需要明确列出所有不同的国家代码,以便匹配类似的东西。或者因为其他人已经了解了这一点,只需要使用一个模块来完成,比如URI::Find-或者如果你只是想要一个正则表达式,那么当然,但是当有人要求一个正则表达式时,解决这个问题总是很有趣的:一般来说,如果答案中包含了对代码意图的解释,以及为什么在不介绍其他代码的情况下解决了问题,那么答案会更有帮助。regexen尤其如此,它因对大多数人来说都是不透明的线噪声而臭名昭著。在这里,也不是特别清楚,它解决了整个问题,因为有答案,而且做得很好,克林顿说:因此,我编写了一个简短的php函数,它使用“parse_url”和一些关于域扩展的观察来准确提取url组件和域名。有人有这个函数的JavaScript版本吗?很好的脚本。使用安全吗?谢谢。我仍然在许多涉及URL和域检查的应用程序上使用它,而且每次都对我有效。我没有PHP来测试你的代码,sub1.sub2.test.co.它在你的情况下有效吗?这是一个不错的小脚本,适用于95%的情况。谢谢我只是想指出,如果域名长度为3个或更少的字母,它将失败www.cnn.com,所以如果你只是复制和粘贴,请小心。问题是不可能知道域是以cnn.com作为TLD的www还是以com作为TLD的cnn。在这种情况下,这很明显,但你需要
现在所有的TLD都可以确定了。这是我最喜欢的答案。谢谢。这不起作用:对于输入www.mail.yahoo.co.来说,所需的输出是mail.yahoo,但这个输出是mail。这很好,接受的答案也不好,但这种方式是可伸缩的,更具动态性。无论您需要特别匹配10-20%的情况,如果这种方法不够,您都可以按照公认的答案进行硬编码。这是对社区的回答,而不是对OP的回答,他已经在11年前收到了他的回答。我认为这里的例子只是为了说明一个一般规则。这只适用于OP提供的输入。
/^(?:https?:\/\/)?(?:www\.)?([^\/]+)/i
var domain;
//find & remove protocol (http, ftp, etc.) and get domain
if (url.indexOf('://') > -1) {
    domain = url.split('/')[2];
} if (url.indexOf('//') === 0) {
    domain = url.split('/')[2];
} else {
    domain = url.split('/')[0];
}

//find & remove port number
domain = domain.split(':')[0];
 var r = /:\/\/(.[^/]+)/;
 "http://stackoverflow.com/questions/5343288/get-url".match(r)[1] 
 => stackoverflow.com
'http://api.livreto.co/books'.replace(/^(https?:\/\/)([a-z]{3}[0-9]?\.)?(\w+)(\.[a-zA-Z]{2,3})(\.[a-zA-Z]{2,3})?.*$/, '$3$4$5');

# returns livreto.co 
function parse_url_all($url){
    $url = substr($url,0,4)=='http'? $url: 'http://'.$url;
    $d = parse_url($url);
    $tmp = explode('.',$d['host']);
    $n = count($tmp);
    if ($n>=2){
        if ($n==4 || ($n==3 && strlen($tmp[($n-2)])<=3)){
            $d['domain'] = $tmp[($n-3)].".".$tmp[($n-2)].".".$tmp[($n-1)];
            $d['domainX'] = $tmp[($n-3)];
        } else {
            $d['domain'] = $tmp[($n-2)].".".$tmp[($n-1)];
            $d['domainX'] = $tmp[($n-2)];
        }
    }
    return $d;
}
$urls = array('www.test.com', 'test.com', 'cp.test.com' .....);
echo "<div style='overflow-x:auto;'>";
echo "<table>";
echo "<tr><th>URL</th><th>Host</th><th>Domain</th><th>Domain X</th></tr>";
foreach ($urls as $url) {
    $info = parse_url_all($url);
    echo "<tr><td>".$url."</td><td>".$info['host'].
    "</td><td>".$info['domain']."</td><td>".$info['domainX']."</td></tr>";
}
echo "</table></div>";
def urlextract(url):
  url_split=url.split(".")
  if len(url_split) <= 2:
      raise Exception("Full url required with subdomain:",url)
  return {'subdomain': url_split[0], 'domain': url_split[1], 'suffix': ".".join(url_split[2:])}
window.location.host.match(/(\w|-)+(?=(\.(com|net|org|info|coop|int|co|ac|ie|co|ai|eu|ca|icu|top|xyz|tk|cn|ga|cf|nl|us|eu|de|hk|am|tv|bingo|blackfriday|gov|edu|mil|arpa|au|ru)(\.|\/|$)))/g)[0]