从URL中提取子域名的正则表达式?

19

我有很多像这样的域名:

http://subdomain.example.com (example.com 的域名不变,但子域名不同)。

我需要获取“子域名”。

能否有耐心学习正则表达式的好心人帮助我?


是的,您可以拥有string.string.domain.gtld。 - Dallas Clark
7个回答

52

以上正则表达式的问题是:如果你不知道协议是什么,或者不知道域名后缀是什么,你将会得到一些意想不到的结果。这里有一个小的正则表达式可以解决这些情况。 :D

/(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/i  //javascript

如果存在子域名,此代码应始终在第1组返回子域名。以下是JavaScript示例,但对于支持正先行断言的任何其他引擎也应该有效:

// EXAMPLE of use
var regex = /(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/i
  , whoKnowsWhatItCouldBe = [
                        "www.mydomain.com/whatever/my-site" //matches: www
                      , "mydomain.com"// does not match
                      , "http://mydomain.com" // does not match
                      , "https://mydomain.com"// does not match
                      , "banana.com/somethingelse" // does not match
                      , "https://banana.com/somethingelse.org" // does not match
                      , "http://what-ever.mydomain.mu" //matches: what-ever
                      , "dev-www.thisdomain.com/whatever" // matches: dev-www
                      , "hot-MamaSitas.SomE_doma-in.au.xxx"//matches: hot-MamaSitas
                  , "http://hot-MamaSitas.SomE_doma-in.au.xxx" // matches: hot-MamaSitas
                  , "пуст.пустыня.ru" //even non english chars! Woohoo! matches: пуст
                  , "пустыня.ru" //does not match
                  ];

// Run a loop and test it out.
for ( var i = 0, length = whoKnowsWhatItCouldBe.length; i < length; i++ ){
    var result = whoKnowsWhatItCouldBe[i].match(regex);
    if(result != null){
      // YAY! We have a match!
    } else {
      // Boo... No subdomain was found
    }
}

4
这显然是最佳答案,因为它考虑了协议、无/多个子域名,并且与域名无关。 - mastaBlasta
我想知道多个子域名的期望输出...你希望它返回 one.two 还是只返回 one?我想我们可以调整正则表达式来提取域名之前的所有 (..) 组...也许稍后再做。 - Pandem1c
干得好,+1。如果你想允许其他协议,可以使用 (file:\/\/|http:\/\/|https:\/\/|\/\/)*(.*?)\.(?=[^\/]*\..{2,5}) - Wesley Smith
在 Google Analytics 中使用这段代码可以按子域过滤 - 必须删除前导 / 和尾随 / i (?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5}) - Ron
1
@WebandFlow,结果SomE_doma-in是您示例的子域名,不是吗?我不清楚您期望得到什么,与您实际得到的有何不同。个人认为匹配应该是SomE_doma-in... - Pandem1c
显示剩余2条评论

24
/(http:\/\/)?(([^.]+)\.)?domain\.com/

如果提供了子域名,$3(或\3)将包含“subdomain”。

如果您希望在第一组中包含子域名,并且您的正则表达式引擎支持非捕获组(shy groups),则可以使用以下内容(由palindrom建议):

/(?:http:\/\/)?(?:([^.]+)\.)?domain\.com/

真的。他没有提到语言/库,所以我想尽可能使正则表达式具有可移植性 - 不确定所有实现是否允许非捕获组。 - Draemon
1
如果你不知道domain是什么怎么办? - Dallas Clark
@DallasClark 在这种情况下,我建议您参考我下面的答案。 - Pandem1c

6

仅包含子域名字符串(结果为 $1):

^http://([^.]+)\.domain\.com

使 http:// 可选(结果为 $2):
^(http://)?([^.]+)\.domain\.com

使 http:// 和子域名可选(结果为 $3):
(http://)?(([^.]+)\.)?domain\.com

2

它应该只是

\Qhttp://\E(\w+)\.domain\.com

子域名将是第一组。

0
#!/usr/bin/perl

use strict;
use warnings;

my $s = 'http://subdomain.example.com';
my $subdomain = (split qr{/{2}|\.}, $s)[1];

print "'$subdomain'\n";

0

为了处理包含点字符的数学子域,我使用了这个方法

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

获取协议后到域名之间的所有匹配字符。

https://sub.domain.com(子域名)

https://sub.sub.domain.com(子子域名)......


-1

第一组

http://(.*).example.com

1
当然,不能忘记 .* 会匹配一个空字符串,更重要的是,句点代表着任意字符 - Sinan Ünür

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